In this guide we will be installing Debian 9 (aka stretch) on a physical server with 4 disks. The role of this machice is to be used as a Storage/NAS system. We will create a software RAID 10 setup, with LVM and LUKS full disk encryption. Our goals:

* Install a Debian 9 with RAID10/LVM/LUKS.
* Secure SSH.
* Enable Firewall (UFW).
* Setup bonding with the two network cards.
* Setup remote system unlock with *dropbear* and *initramfs*.
* Setup disk-monitoring with *smartmontools* and *mdadm*.
* Setup *kexec* for faster reboots.

## Computer specs

* Type: HP ProLiant MicroServer
* CPU: AMD Turion(tm) II Neo N40L Dual-Core Processor
* RAM: 2GB
* Disks: 4x3TB SATA
* Network:
* Broadcom Limited NetXtreme BCM5723 Gigabit Ethernet PCIe (on board)
* Intel Corporation 82574L Gigabit Network Connection (extra)

## Assumptions

* Server IP: 192.168.1.10
* Netmask: 255.255.255.0
* Gateway IP: 192.168.1.1
* DNS IP: 192.168.1.1
* Hostname: storage.example.com

## Install Debian stretch

### Basic Settings

It would probably be more clear if there were screenshots for each step, but this was an installation on a physical server and taking photos for each step, opposes my laziness :). Just follow the instructions and you will be fine.

* Choose: **Install**
* Language: **English**
* Country: **other**
* Europe: **Cyprus**
* Country to base default locale settings: **United States**
* Keymap to use: **American English**
* Primary network interface: **enp3s0: Broadcom Limeted NetXtream BCM5723 Gigabit Ethernet PCIe**
* Let it get an IP from DHCP
* Hostname: **storage**
* Domain name: **example.com**
* Root password: **SomethingBigAndUnpredictable**
* Re-enter password to verify: **SomethingBigAndUnpredictable**
* Full name: **Sysadmin**
* Username: **admin**
* Choose a password for the new user: **AlsoSomethingBigAndUnpredictable**
* Re-enter password to verify: **AlsoSomethingBigAndUnpredictable**
* Select your time zone: **Asia/Nicosia**
* Partitioning method: **Manual**

Feel free to adjust the above according to your own preferences.

### Partitioning

There are 4 disks of 3TB each (3.0 TB SATA):

* SCSI1 (0,0,0) (sda)
* SCSI2 (0,0,0) (sdb)
* SCSI3 (0,0,0) (sdc)
* SCSI4 (0,0,0) (sdd)

Not really SCSI but SATA in fact.

#### Partition the devices

Then create a raid partition for */boot*:

* Select the free space of sda and ‘Enter’
* Create a new partition
* New partition size: **512 MB**
* Location of new partition: **Beginning**
* Use as: **physical volume for RAID**
* Done setting up the partition

Lastly create the raid partition to be used by the encrypted volume:

* Select the free space of sda and ‘Enter’
* Create a new partition
* New partition size: **3.0 TB**
* Location of new partition: **Beginning**
* Use as: **physical volume for RAID**
* Done setting up the partition

Repeat the above steps for sdb, sdc and sdd.

#### Setup Software RAID 10

First select ‘Configure software RAID’ and follow these steps:

* Write the changes to the storage devices and configure RAID? **Yes**

The we create the software RAID (MD) devices. First we create device *md0* for /boot:

* Create MD Device
* RAID10
* Number of active devices inn the RAID10 array: **4**
* Number of spare devices inn the RAID10 array: **0**
* Active devices for the RAID10 array (use ‘Space bar’ to select)
* **/dev/sda2**
* **/dev/sdb2**
* **/dev/sdc2**
* **/dev/sdd2**
* Press ‘Continue’ when done.

Then we create the software RAID device to be used for the encrypted volume (*md1*):

* Create MD Device
* RAID10
* Number of active devices inn the RAID10 array: **4**
* Number of spare devices inn the RAID10 array: **0**
* Active devices for the RAID10 array (use the ‘Space bar’ to select)
* **/dev/sda3**
* **/dev/sdb3**
* **/dev/sdc3**
* **/dev/sdd3**
* Press ‘Continue’ when done.

* Press ‘Finish’ when done.

#### Create the /boot volume

When done press ‘Finish partitioning and write changes to disk’.`

When finished you will see a ‘RAID10 device #0 1GB Software RAID device’:

* Select: #1 1.0GB
* Use as: **Ext4 journaling file system**
* Mount point: **/boot**
* Done setting up the partition

#### Setup the encrypted volume

We will be using the software RAID */dev/md1* device for the encrypted volume.

Now select ‘Configure encrypted volumes’ and follow these steps:

* Write the changes to disk and configure encrypted volumes? **Yes**

* Create encrypted volumes
* Select: */dev/md1*
* Erase data: **yes** (this will take a long time)
* Done setting up the partition

* Write the changes to disk and configure encrypted volumes? **Yes**
* Finish
* Encryption passphrase: **MyVeryLongEncryptionPassphrase**
* Re-enter the passphrase to verify: **MyVeryLongEncryptionPassphrase**

#### Setup LVM

Next we select the ‘Configure the Logical Volume Manager’ option and follow these steps:

* Write the changes to disks and configure LVM? **Yes**

* Create volume group
* Volume group name: **VG00**
* Devices for the new volume group:
* /dev/mapper/md1_crypt

Then we create the Logical Volumes (LV). First let’s create a SWAP volume:

* Create logical volume
* Volume group: **VG00**
* Logical volume name: **SWAP**
* Logical volume size: **2048MB** (2G is more than enough for this system)

Lastly we create the system (ROOT) volume. On an enterprise installation we may want to use different volumes for /usr, /home, /var, etc but for a home installation we will be fine to use just one.

* Create logical volume
* Volume group: **VG00**
* Logical volume name: **ROOT**
* Logical volume size: **5996818MB** (All available space)

Press ‘Finish’ when done.

### Start the installation

After all the steps are completed these Logical Volumes will be present on the system:

* LVM VG VG00, LV ROOT 0 6.0 TB
* LVM VG VG00, LV SWAP 0 2.0 GB

#### Create the ROOT filesystem

Under the ‘LVM VG VG00, LV ROOT 0 6.0 TB’ line select the ‘#1 6.0TB’ option:

* Use as: **Ext4 journaling file system**
* Mount point: **/**
* Done setting up this partition

#### Create the SWAP space

Under the ‘LVM VG VG00, LV SWAP 0 2.0 GB’ line select the ‘#1 2.0GB’ option:

* Use as: **swap area**
* Done setting up this partition

Now we are ready to write the changes and start the installation. Press the ‘Finish partitioning and write changes to disk’ option to continue:

* Write the changes to disks? **Yes**

Wait for the base install to finish. Then select a country close to you. No debian mirrors in Cyprus so I use UK:

* Debian archive mirror country: **United Kingdom**
* Debian archive mirror: **ftp.uk.debian.org**
* HTTP proxy: (none)

Wait for the APT configuration to Finish.

* Participate in the package usage survey: **no**

* Choose software to install:
* SSH server
* standard system utilities

Wait while software is installing

* Install the GRUB boot loader to the master boot record.
* Device for boot loader installation:
* **/dev/sda**

Wait for the installation to finish and reboot. Remember to remove the USB during the reboot cycle.

## Post install steps

During start-up you will see the ‘Please unlock md1_crypt’ prompt. Type your LUKS passphrase to unlock the disk and continue.

### Update and Upgrade

Login as *root*:

“`
# apt update && apt -y dist-upgrade
“`

### Install essential packages

“`
# apt -y install vim htop multitail ntp byobu ufw unattended-upgrades downtimed
“`

### Secure ssh

You need to generate an SSH key pair on you PC, if you don’t have one (you should!):

“`
$ ssh-keygen -b 4096
“`

Copy the public key:

“`
$ cat ~/.ssh/id_rsa.pub
“`

Paste the public key at the end of the */root/.ssh/authorized_keys* file in your server and try to login from your PC:

“`
$ ssh root@192.168.1.10
“`

Some final adjustments on your *SSH* config (*/etc/ssh/sshd_config*). Change these values:

“`
Port 2233
PasswordAuthentication no
“`

Restart *SSH*:

“`
# systemctl restart ssh.service
“`

### Enable the UFW firewall

We are using port 2233 for *SSH* so we need to allow that and enable the firewall:

“`
# ufw allow 2233/tcp
# ufw enable
“`

### Setup bonding

Since we have two ethernet cards, we may take advantage of thr Linux bonding feature and join them as one. We will be using the *Adaptive load balancing* mode which provides load balancing of transmit, load balancing of receive for IPv4 and requires no configuration from the switch side.

First we need to install *ifenslave*:

“`
# apt -y install ifenslave
“`

Set up this in */etc/network/interfaces*:

“`
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# enp2s0 is manually configured, and slave to the “bond0″ bonded NIC
auto enp2s0
iface eth0 inet manual
bond-master bond0

# enp3s01 is also manually configured, thus creating a 2-link bond.
auto enp3s0
iface eth1 inet manual
bond-master bond0

# bond0 is the bonded NIC and can be used like any other normal NIC.
# bond0 is configured using static network information.
auto bond0
iface bond0 inet static
address 192.168.1.10
gateway 192.168.1.1
netmask 255.255.255.0

# bond0 uses adaptive load balancing
bond-mode 6
bond-miimon 100
bond-slaves enp2s0 enp3s0
“`

An `ifup bond0` should bring the bonded interface up. Or you can just `reboot`.

### Setup remote-unlock with dropbear

The server will be a headless system, located in a difficult to access location. So we need a way to unlock it when a power failure occurs. The most convenient way to do this is to use a [mandos server](https://wiki.recompile.se/wiki/Mandos) but convenience comes at a [cost](https://www.recompile.se/mandos/man/intro.8mandos). A safer and easier way is to use dropbear during boot (initrd). The weak point of this solution is that the server will be basically offline until the sysadmin manually unlocks it, to boot.

First we install *dropbear* for *initrd*:

“`
# apt -y install dropbear-initramfs
“`

Then we set a custom ssh port for *dropbear*. This better be different than the custom ssh port we used earlier. Change the dropbear port to 2244 in /etc/dropbear-initramfs/config:

“`
DROPBEAR_OPTIONS=”-p 2244″
“`

Add the static IP in the initramtools configuration (*/etc/initramfs-tools/initramfs.conf*):

“`
IP=192.168.1.10::192.168.1.1:255.255.255.0:storage:enp3s0:off
“`

Copy the *authorized_keys* file in */etc/dropbear-initramfs*:

“`
# cp /root/.ssh/authorized_keys /etc/dropbear-initramfs/
“`

Regenerate the initrd file:

“`
# update-initramfs -u
“`

Now reboot and ssh to it to test it:

“`
$ ssh -p 2244 root@192.168.1.10
“`

If your pubkeys are in place you will enter a busybox shell. Enter the `crypt-unlock` command, supply your unlock passphrase and the system will boot to the encrypted system.

### Setup a local MTA for notifications

We will be using our main mailserver as a smarthost for mail to go through.

Install the *postfix* MTA and the *mail* utility:

“`
# apt -y install postfix mailutils
“`

Answer these questions:

* General type of mail configuration: **Internet with smarthost**
* System mail name: **storage.example.com**
* SMTP relay host (blank for none): **smtp.example.com**

Test it:

“`
# echo ‘Testing #1’ | mail -s ‘Test #1’ user@example.com
“`

If you get a mail in your mailbox then everything is set. If not extra configuration may be needed on the smarthost. Contact the sysadmin of the smarthost, or check the logs if you access to it.

### Setup pro-active disk monitoring

Install *smartmontools*:

“`
# apt -y install smartmontools
“`

Enable S.M.A.R.T, offline testing, attribute autosave, short and long test on all 4 devices. Add these lines in */etc/smartd.conf*:

“`
/dev/sda -a -d sat -o on -S on -s (S/../.././02|L/../../6/03) -m user@example.com -M exec /usr/share/smartmontools/smartd-runner
/dev/sdb -a -d sat -o on -S on -s (S/../.././02|L/../../6/03) -m user@example.com -M exec /usr/share/smartmontools/smartd-runner
/dev/sdc -a -d sat -o on -S on -s (S/../.././02|L/../../6/03) -m user@example.com -M exec /usr/share/smartmontools/smartd-runner
/dev/sdd -a -d sat -o on -S on -s (S/../.././02|L/../../6/03) -m user@example.com -M exec /usr/share/smartmontools/smartd-runner
“`

Restart *smartmontools*:

“`
# systemctl restart smartmontools.service
“`

### Setup Software RAID10 monitoring

We also need to setup monitoring for the software raid. Add your email address in the */etc/mdadm/mdadm.conf* file:

“`
MAILADDR user@example.com
“`

Restart the *mdmonitor* service:

“`
# systemctl restart mdmonitor.service
“`

### Setup kexec for faster reboots

*Kexec* is a Linux kernel mechanism that can load a fresh kernel from a running system. This results in a “reboot” without in fact rebooting the computer. The system loads a new kernel, the system appears “rebooted” but skipping the BIOS?UEFI initialization, thus resulting in faster reboots.

Install *kexec-tools*:

“`
# apt -y install kexec-tools
“`

The ‘Should kexec-tools handle reboots (sysvinit only)?’ question is related only to *sysvinit* systems. Since we are using *systemd*, it has no effect in our case.

Now if you want to reboot instead of running `reboot` you can run `systemctl kexec`. The latter command will reboot the system without going though BIOS/UEFI, POST etc and your system downtime is minimized.

And we are done! Store your server in a protected location, add a UPS for power backup and you are ready.

References
———-
* https://wiki.debian.org/Bonding
* https://help.ubuntu.com/community/UbuntuBonding
* https://www.theo-andreou.org/?p=1579
* https://wiki.recompile.se/wiki/Mandos
* http://forums.ayksolutions.com/forum/documentation/knowledgebase/general-server-questions/641-proactively-monitoring-hard-drive-health-using-smartd

*LXD* is a relatively new technology by Canonical. It is a [container](https://en.wikipedia.org/wiki/Container_(virtualization)) hypervisor that builds on top of [LXC](https://en.wikipedia.org/wiki/LXC). It shares some similarities with Docker, but LXD focuses on full blown containerized systems, instead of containerized applications.

LXD/LXC creates lighter systems than VM hypervisors, and it is an easy way to experiment with different software without messing up with your system. You can also use it in production, to run Linux systems with much greater density than on VM hypervisors. The only drawback is that the container must be the same OS as the host (Linux in this case) and it depends on the host for kernel functionality (e.g. modules etc).

In this guide we will build an LXD container with two virtual [NICs](https://en.wikipedia.org/wiki/Network_interface_controller) which are attached to the physical NIC of it’s host using bridged networking.

## Prerequisites

* An Ubuntu 16.04 host with two physical NICs

## Prepare host networking

### Install dependencies

“`
# apt -y install bridge-utils
“`

### Setup networking on the host

There are two interfaces on the host *enp3s0* and *enp5s0*. The first one, enp3s0 is the primary and connects to the main, DHCP enabled, internal network. The second one is connected to an isolated internal network where some critical services are running. There is no DHCP in the isolated network.

Prepare your */etc/network/interfaces* configuration file like this:

“`
# The loopback network interface
auto lo
iface lo inet loopback

# The main Bridge
auto br0
iface br0 inet dhcp
bridge-ifaces enp3s0
bridge-ports enp3s0
up ip link set enp3s0 up

# The primary network interface
iface enp3s0 inet manual

# The secondary Bridge
auto br1
iface br1 inet manual
bridge-ifaces enp5s0
bridge-ports enp5s0
up ip link set enp5s0 up

# The secondary network interface
iface enp5s0 inet manual
“`

## Setup LXC/ LXD

### Installation of LXD

“`
# apt -y install lxd
“`

### Prepare a new profile

We need a profile with two NICs. First create a new profile:

“`
# lxc profile copy default dualnic
“`

Then edit the new profile with `lxc profile edit dualnic`:

“`
config:
user.network_mode: link-local
description: Dual nic profile
devices:
eth0:
name: eth0
nictype: bridged
parent: br0
type: nic
eth1:
name: eth1
nictype: bridged
parent: br1
type: nic
name: dualnic
“`

The names of the virtual interfaces of the container will be *eth0* for the primary and *eth1* for the secondary.

### Launch the container

Now we want to launch a Debian jessie container, which we will retrieve from the prepared images on the

“`
# lxc launch images:debian/jessie mycontainer -p dualnic
“`

List the container:

“`
# lxc list
+————-+———+———————-+——+————+———–+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+————-+———+———————-+——+————+———–+
| mycontainer | RUNNING | 192.168.0.122 (eth0) | | PERSISTENT | 0 |
+————-+———+———————-+——+————+———–+
“`

The IP listed above was set by the DHCP server in the primary network.

Connect to the container:

“`
# lxc exec mycontainer bash
“`

### Setup container’s networking

Edit */etc/network/interfaces* inside our container:

“`
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

auto eth1
iface eth1 inet static
address 172.16.16.100
netmask 255.255.255.0
network 172.16.16.0
broadcast 172.16.16.255
up ip route add 10.10.10.0/24 via 172.16.16.1 dev eth1
up ip route add 10.10.20.0/24 via 172.16.16.1 dev eth1
“`

The routes 10.10.10.0/24 and 10.10.20.0/24 are internal routes that need to be reached though the secondary network.

### Take a clean snapshot

Before you start working on your container, it is a good idea to get a clean snapshot, so you can revert to it, in case you mess something up.

“`
# lxc snapshot mycontainer
“`

If you want to learn more about the and features I urge you to read the excellent [introduction to LXD 2.0](https://insights.ubuntu.com/2016/03/14/the-lxd-2-0-story-prologue/) by [Stéphane Graber](https://insights.ubuntu.com/author/stgraber/)

References
———-
* https://linuxcontainers.org/
* https://www.ubuntu.com/containers/lxd
* https://insights.ubuntu.com/2016/03/14/the-lxd-2-0-story-prologue/
* https://stgraber.org/2016/03/11/lxd-2-0-blog-post-series-012/
* https://insights.ubuntu.com/2015/11/10/converting-eth0-to-br0-and-getting-all-your-lxc-or-lxd-onto-your-lan/

[Rocket.Chat](https://rocket.chat) is a free/open source software for team collaboration. It is a [full featured](https://rocket.chat/features) platform and an ideal alternative to [Slack](https://en.wikipedia.org/wiki/Slack_(software)), for organizations that are dedicated to the Free Software philosophy.

In this guide we will demonstrate how you can setup Rocket.Chat for your organization.

## Prerequisites

* A Debian stretch VM or server.
* A FQDN pointing to the system’s IP. We will be using *rocket.example.com* throughout this guide.

## Installation of rocket.chat

### Install the Snappy package manager

*Snappy* is not installed on Debian by default, so we need to install it:

“`
# apt install snapd ca-certificates
“`

### Install Rocket.Chat

“`
# snap install rocketchat-server
“`

Check its status:

“`
# systemctl status snap.rocketchat-server.rocketchat-server.service
● snap.rocketchat-server.rocketchat-server.service – Service for snap application rocketchat-server.rocketchat-server
Loaded: loaded (/etc/systemd/system/snap.rocketchat-server.rocketchat-server.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2017-01-03 12:27:50 PST; 12min ago
Main PID: 24891 (node)
Tasks: 10 (limit: 4915)
CGroup: /system.slice/snap.rocketchat-server.rocketchat-server.service
└─24891 node /snap/rocketchat-server/326/main.js

Jan 03 12:27:50 rocket systemd[1]: Started Service for snap application rocketchat-server.rocketchat-server.
“`

Check its port (default is 3000):

“`
# ss -lnptu | grep 3000
tcp LISTEN 0 128 *:3000 *:* users:((“node”,pid=24891,fd=13))
“`

Looks OK

## Configure TLS

### Install nginx

The core application does not support TLS so we will be setting up an nginx reverse proxy on top of it.

Install *NGINX* and *certbot* from *Let’s Encrypt*:

“`
# apt -y install nginx python-certbot-nginx
“`

### Create the VirtualHost

We need to create this file: */etc/nginx/sites-available/rocket.example.com*:

“`
# Upstreams
upstream backend {
server 127.0.0.1:3000;
}

# HTTP Server
server {
listen 80;
server_name rocket.example.com;

error_log /var/log/nginx/rocketchat.access.log;

location / {
proxy_pass http://127.0.0.1:3000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “upgrade”;
proxy_set_header Host $http_host;

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forward-Proto http;
proxy_set_header X-Nginx-Proxy true;

proxy_redirect off;
}
}
“`

Enable the VirtualHost:

“`
cd /etc/nginx/sites-enabled/
ln -s ../sites-available/rocket.example.com
systemctl reload nginx
“`

### Generate the certificate

“`certification
certbot –nginx run -d rocket.example.com
“`

* Enter email address: **admin@example.com**
* Agree to the ToS
* Enforce HTTPS: **Secure**

The VirtualHost file (*/etc/nginx/sites-available/rocket.example.com*) should look like this after the creation of the Let’s Encrypt certificate:

“`
# Upstreams
upstream backend {
server 127.0.0.1:3000;
}

server {
listen 80;
server_name rocket.example.com;

error_log /var/log/nginx/rocketchat.access.log;

location / {
proxy_pass http://127.0.0.1:3000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “upgrade”;
proxy_set_header Host $http_host;

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forward-Proto http;
proxy_set_header X-Nginx-Proxy true;

proxy_redirect off;
}

listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/rocket.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/rocket.example.com/privkey.pem; # managed by Certbot
ssl_session_cache shared:le_nginx_SSL:1m; # managed by Certbot
ssl_session_timeout 1440m; # managed by Certbot

ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # managed by Certbot
ssl_prefer_server_ciphers on; # managed by Certbot

ssl_ciphers “ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA ECDHE-ECDSA-AES256-SHA ECDHE-ECDSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-SHA ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES256-SHA384 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA DHE-RSA-AES128-SHA256 DHE-RSA-AES256-SHA256 EDH-RSA-DES-CBC3-SHA”; # managed by Certbot

if ($scheme != “https”) {
return 301 https://$host$request_uri;
} # managed by Certbot
}
“`

Now visit the website to test it: http://rocket.example.com (it should redirect you to https://rocket.example.com)

## Creating an admin account

Register a new account. You will get this warning:

**WARNING: the setting site URL is configured to http://localhost and you are accessing from https://rocket.example.com. do you want to change to https://rocket.example.com?**

You should ofcourse answer ‘Yes’.

This first user created is an admin user. You can set global preferences from https://rocket.example.com/admin. Now users can visit the website and register with it. You may wish to **Allow Notifications** when you are prompted by your browser on your first visit to the site. Rocket.Chat supports many other authentication backends, including LDAP which is described in the next step.

Besides the web service you can also download [native applications](https://rocket.chat/download) for Linux, Windows, Mac OS X, Android and iOS.

## Configure LDAP

This is an optional step, but recommended if your organization has an LDAP or Active Directory setup. In this example we are using the [Fusiondirectory setup](http://www.theo-andreou.org/?p=1539) from our previous guide.

Create a service account for rocket.chat, using the DSA module of Fusiondirectory:

* Username: **cn=rocketchat,ou=dsa,dc=example,dc=com**
* Password: **MySecretCombination**

Now go to https://rocket.example.com/admin using an admin account and set these:

* Enable: **True**
* Login Fallback: **True**
* Host: **ldap.example.com**
* Port: **389**
* Encryption: **StartTLS**
* CA Cert: **Paste the contents of your internal ROOT CA certificate (example.com-rootCA.crt for example)**
* Reject Unauthorized: **True**
* Domain Base: **ou=people,dc=example,dc=com**
* Use Custom Domain Search: **False**
* Domain Search User: **cn=rocketchat,ou=dsa,example,dc=com**
* Domain Search Password: **MySecretCombination**
* Domain Search User ID: **uid**
* Domain Search Object Class: **person**
* Domain Search Object Category: **Leave Empty**
* Username Field: **Leave Empty**

Leave the default settings for the rest and press the **SAVE CHANGES** button

You can use the **TEST CONNECTION** button to test the connection.

You can now try to login using your LDAP username and password.

References
————
* https://rocket.chat/
* http://snapcraft.io/docs/core/install#debian
* https://rocket.chat/docs/installation/manual-installation/ubuntu/snaps
* https://rocket.chat/docs/installation/manual-installation/configuring-ssl-reverse-proxy
* https://rocket.chat/docs/administrator-guides/authentication/ldap/

Less than a year ago I was attracted by the value for money offer of OnePlus 2 and became a proud owner. Being paranoid about Google tracking, I disabled most Google apps. Alas, some apps were impossible to disable. I assumed that this was caused by their dependencies with other core applications. Google play services was one them, but I never created an account with Google and never synced anything with them.

Time went by and it happened that data over mobile was accidentally enabled. And then I noticed from the mobile data traffic statistics, that Google Play services was creating traffic even without a Google account! Why does this happens its beyond my perception, but anyone is allowed to guess based on [recent history](https://en.wikipedia.org/wiki/PRISM_(surveillance_program)#/media/File:Prism_slide_5.jpg “PRISM Surveillance program”). There is an option to disable background traffic on the stock Android ROM (OxygenOS) but that works only when data over mobile is enabled. With Wi-Fi enabled, Google Play services keeps on sending suspicious traffic, back to mother Google.

So I decided to look for alternatives to replace OxygenOS with a Google-free Android ROM. These are the options I have investigated:
* [Replicant](http://www.replicant.us/): This seems to be the more privacy respecting Android MOD. No support for OnePlus 2, alas!
* [AOKP](http://aokp.co): This is an interesting MOD with lots of features. There are recent nightly builds for OnePlus 2. I tried to install it my Phone but gave an error when I tried to sideload it.
* [CyanogenMOD](https://web.archive.org/web/20161225144318/https://www.cyanogenmod.org/blog/a-fork-in-the-road): A popular Android MOD that was [recently discontinued](https://twitter.com/CyanogenMod/status/813086249506349056). A fork by the name [LineageOS](http://lineageos.org/) is taking over. No image downloads yet.
**UPDATE (2-Jan-2016): There are some experimental LineageOS images [here](http://www.lineageosrom.com/2016/12/rom-download-linage-os-for-oneplus-2.html).**
* [Paranoid Android](http://www.paranoidandroid.co/): Another successful Android MOD with [close ties to OnePlus](http://www.androidauthority.com/oneplus-paranoid-android-team-587101/). It boasts some interesting features. Officially supports all OnePlus models except the latest OnePlus 3T. I tried the OnePlus 2 image but the phone stack to the OnePlus logo boot screen.
* [Exodus](https://github.com/TeamExodus): This is a minimalistic Android MOD. It is based on [AOSP](https://source.android.com/) and is free from Google Apps. This is the only MOD I managed to get it working on my OnePlus 2.

So I decided to go with Exodus. This guide describes the procedure and preparations I followed in order to flash the latest Exodus nightly build for OnePlus 2.

**DISCLAIMER: This guide could renter your device a luxurious brick! Backup everything before you continue. The author of this guide will not be liable for any damages you may cause on your device or any data lost. Proceed at your own risk!**

Now we got that out of the way, let’s continue.

## Prerequisites

* A PC. In this guide we are using Debian/Ubuntu as the PC’s Operating System but this can work with other Operating Systems, with minor adaptations.
* An OnePlus 2 smartphone. It could possibly be used for other devices too, but I have only tested this on OnePlus 2.
* The [Android Debug Bridge (ADB)](https://developer.android.com/studio/command-line/adb.html). This is part of the [Android SDK](https://developer.android.com/studio/index.html). On Debian/Ubuntu you can install it with `apt install android-tools-adb`.
* A [Type-C USB](https://en.wikipedia.org/wiki/USB_Type-C) cable to connect the phone to your PC.

## Make your device detectable in Linux

There is some process we need to follow so that the OnePlus 2 device is detectable by ADB

### Enable Usb Debugging

To Enable *USB Debugging* we need to first enable the *Developer Options*:

* Go into *Settings*
* Dive into the *About phone* option
* Tap 7 times on the *Build number* option
* Go back and tap on *Developer Options*
* Enable *USB debugging* and *OEM unlock*

### Enable detection of device under Linux

First ensure that the device is connected:

“`
# lsusb

Bus 003 Device 039: ID 2a70:f003

“`

The device ID for OnePlus 2 is **0x2a70**. Set this in * ~/.android/adb_usb.ini*:

“`
# echo “0x2a70” >> ~/.android/adb_usb.ini
“`

Download the udev rules files (Thanks [Nicolas Bernaerts](http://bernaerts.dyndns.org/android/339-android-oneplustwo-oneplusx-enable-adb-mtp-detection-ubuntu-trusty)):

“`
# wget –header=’Accept-Encoding:none’ -O /etc/udev/rules.d/51-android.rules https://raw.githubusercontent.com/NicolasBernaerts/ubuntu-scripts/master/android/51-android.rules
# chmod a+r /etc/udev/rules.d/51-android.rules
# wget –header=’Accept-Encoding:none’ -O /etc/udev/rules.d/69-mtp.rules https://raw.githubusercontent.com/NicolasBernaerts/ubuntu-scripts/master/android/69-mtp.rules
# chmod a+r /etc/udev/rules.d/69-mtp.rules
“`

Restart the *udev* and *ADB* services:

“`
# systemctl restart udev
# adb kill-server
# adb start-server
“`

**NOTE: make sure USB Debugging is enabled otherwise you will still not be able to see the device!**

Verify that the device is present:

“`
# adb devices
List of devices attached
da0afea7 unauthorized
“`

Seems OK.

## Backup your data and stock image

Since we are not using Google’s services we will need to manually backup all important data such as:

* Export contacts on a *.vcf* file.
* Save Pictures and Videos from the phone on your PC
* Backup every other Applacation data which is important to you.

You can also backup your entire system with ADB:

“`
# adb backup -f oneplus2.bck -apk -shared -all
“`

This will take some time depending on the size of your data.

You can later restore your system back to normal, using this command:

“`
# adb restore oneplus2.bck
“`

## Prepare the recovery image

Download Prepare the First Aid kit

This is a bundle that includes all the files needed to bring life to a bricked OnePlus 2 device. It includes a recovery image which we will use to install Exodus (or any other image you wish) on the device.

“`
# wget -O Firstaid_v_2_0.zip ‘http://forum.xda-developers.com/devdb/project/dl/?id=16684&task=get’
# unzip Firstaid_v_2_0.zip
“`

All the necessary files are in the newly created, *Firstaid* directory.

### Download TWRP Custom recovery

The recovery image that comes with *Firstaid* is somewhat outdated. We will download a more recent version of it and replace it in the Firstaid directory. You can download the more recent [TWRP](https://twrp.me/) image from [here](https://dl.twrp.me/oneplus2/twrp-3.0.2-0-oneplus2.img.html). Do not use `wget` or other command line tools, just a normal browser to download it.

**NOTE: There are more recent versions than 3.0.2-0 like 3.0.2-1 and 3.0.2-2. You can try those if you feel lucky, but be warned! Those versions did not work on my phone. You can see all the past and resent images [here](https://dl.twrp.me/oneplus2/).**

Verify the downloaded image:

“`
# wget -O twrp-public.asc https://dl.twrp.me/public.asc
# gpg –import twrp-public.asc
# wget https://dl.twrp.me/oneplus2/twrp-3.0.2-0-oneplus2.img.asc
# gpg –verify twrp-3.0.2-0-oneplus2.img.asc twrp-3.0.2-0-oneplus2.img
“`

If you get `Good signature from “TeamWin “` that means the image is correct. Now replace the TWRP image that comes with Firstaid with this one:

“`
# cp twrp-3.0.2-0-oneplus2.img Firstaid/twrp.img
“`

## Flash the recovery image

Reboot to fastboot mode:

“`
# adb reboot-bootloader
“`

Alternatively you can poweroff the OnePlus 2 and press the Volume UP + Power buttons simultaneously.

Verify the presence of the device:

“`
# fastboot devices
da0afea7 fastboot
“`

Unlock the phone:

“`
fastboot oem unlock
“`

Flash Firstaid with the recent TWRP recovery image:

“`
# cd Firstaid
# ./firstaid.sh
“`

Now unplug the phone from the PC, poweroff and the press the Volume DOWN + Power buttons simultaneously. This will bring your phone into TWRP recovery.

## Flashing the Exodus image

### Download Exodus image and verify

Download the latest Exodus image for OnePlus 2 [here](http://exodus-developers.net/exodus-6.0/oneplus2/exodus-6.0-20161111-NIGHTLY-oneplus2.zip):

“`
# wget http://exodus-developers.net/exodus-6.0/oneplus2/exodus-6.0-20161111-NIGHTLY-oneplus2.zip
# wget http://exodus-developers.net/exodus-6.0/oneplus2/exodus-6.0-20161111-NIGHTLY-oneplus2.zip.md5
“`

Verify that the download is correct:

“`
# cat exodus-6.0-20161111-NIGHTLY-oneplus2.zip.md5 ; md5sum exodus-6.0-20161111-NIGHTLY-oneplus2.zip
35dcf9ea73648682a36e673f5ed8f0eb /android/exodus-6.0/out/target/product/oneplus2/exodus-6.0-20161111-NIGHTLY-oneplus2.zip
35dcf9ea73648682a36e673f5ed8f0eb exodus-6.0-20161111-NIGHTLY-oneplus2.zip
“`

Seems OK

Plug the phone back to the PC and ensure that it is detectable by ADB:

“`
# adb devices
List of devices attached
da0afea7 device
“`

### Flash the Exodus image

Follow these steps:

* Wipe old data: Select *Wipe* and then *Swipe to Factory Reset*. You may need to format the system if the previous system was encrypted.
* Enter the Sideload mode: From the TWRP start menu select *Advanced* then *ADB Sideload* and then *Swipe to Start Sideload*
* From the PC’s CLI run the following command:

“`
# adb sideload exodus-6.0-20161111-NIGHTLY-oneplus2.zip
“`

Wait and then reboot into the new Exodus system when done.

### Optional steps

#### Install F-Droid:

By default Exodus has a minimal set of apps. Since we are not using Google Apps we will need to install F-Droid:

“`
# wget https://f-droid.org/FDroid.apk
# adb install FDroid.apk
“`

#### Lock your Phone

Setup a PIN or Pattern to lock the screen of your phone when not in use: *Settings* -> *Security* -> *Screen Lock*. Avoid fingerprint as it can be easily bypassed.

#### Encrypt phone

Encrypting your phone will protect your data if it gets stolen or confiscated. These are the steps *Settings* -> *Security* -> *Encrypt phone*. Your phone will need to be plugged to charger and charged to 80% or above, otherwise the system will refuse to start the encryption process.

## Restoring the Stock OxygenOS System

If you decide that you don’t like Exodus or any other MOD that you have installed, you can restore your phone back to the stock OxygenOS. These instructions can also be used to restore your phone’s functionality after you have accidentally bricked it.

### Download necessary images

Download the stock OxygenOS 3.0.2 image from [here](https://www.androidfilehost.com/?fid=24580917854994435). Verify the download with:

“`
# echo 46b1fde116275d83d05c2dd89422069f ; md5sum OnePlus2Oxygen_14_OTA_019_all_1606041303.zip
46b1fde116275d83d05c2dd89422069f
46b1fde116275d83d05c2dd89422069f OnePlus2Oxygen_14_OTA_019_all_1606041303.zip
“`

Download the upgrade patch for Oxygen 3.1.0 from [here](https://www.androidfilehost.com/?fid=24591000424963091). Verify the download with:

“`
# echo 9cfa9a2a4c7fada6f9db79ea660251d0 ; md5sum OnePlus2Oxygen_14_OTA_019-020_patch_1608262242.zip
9cfa9a2a4c7fada6f9db79ea660251d0
9cfa9a2a4c7fada6f9db79ea660251d0 OnePlus2Oxygen_14_OTA_019-020_patch_1608262242.zip
“`

Optionally you can download the [SuperSU](https://download.chainfire.eu/743/supersu) image if you would like your OxygenOS rooted:

“`
# wget -O supersu.zip ‘https://download.chainfire.eu/743/SuperSU/BETA-SuperSU-v2.52.zip?retrieve_file=1’
“`

### Flash Recover image

First we need to restore the recovery ROM from Firstaid:

“`
# cd Firstaid
# ./firstaid.sh
“`

### Flash the Oxygen Images.

Before we install the OxygenOS image it is recommended to wipe the phone: From the TWRP menu select *Wipe* and then *Swipe to factory reset*. If the system was previously encrypted you will need to use TWRP to format it before the wipe.

Then we need to set the device into Sideload mode: Select *Advanced* -> *ADB Sideload* -> *Swipe to Start Sideload*.

First install the OxygenOS 3.0.2 image:

“`
adb sideload OnePlus2Oxygen_14_OTA_019_all_1606041303.zip
“`

Then re-enable ADB Sideload and load the Oxygen 3.2.0 patch:

“`
adb sideload OnePlus2Oxygen_14_OTA_019-020_patch_1608262242.zip
“`

Optionally you can also load the SuperSU application as well

“`
adb sideload supersu.zip
“`

Finally reboot into the new system and enjoy your freshly formatted phone.

References
———–
* http://bernaerts.dyndns.org/android/339-android-oneplustwo-oneplusx-enable-adb-mtp-detection-ubuntu-trusty
* https://forum.xda-developers.com/devdb/project/dl/?id=16684
* https://twrp.me/
* https://twrp.me/devices/oneplustwo.html
* https://github.com/TeamExodus/device_oneplus_oneplus2
* http://exodus-developers.net/
* https://github.com/TeamExodus/device_oneplus_oneplus2

Most registrars they provide a DNS service when you purchase a domain name. But having your own DNS servers means more control to you. And if you are an aspiring sysadmin, you will find it fun and educational. We will be using [BIND 9](https://en.wikipedia.org/wiki/BIND) which is, by far the most popular DNS implementation.

## Prerequisites

We will need two systems (VMs or containers) preferably on different geographic locations and different providers. One will be the master and the other system, the slave. This guide works for recent Debian or Ubuntu systems.

Some assumptions:

* Master DNS:
* Hostname: **ns1.example.com**
* IP: **1.1.1.1**
* Slave DNS:
* Hostname: **ns2.example.com**
* IP: **2.2.2.2**
* Webserver:
* Hostname: **example.com** (*www.example.com* is an alias)
* IP: **3.3.3.3**
* Main mailserver:
* Hostname: **mx1.example.com** (*{mail,smtp,pop,imap,webmail}.example.com* are aliases)
* IP: **4.4.4.4**
* Backup mailserver:
* Hostname: **mx2.example.com**
* IP: **5.5.5.5**

## Preparations

### Setup the */etc/hosts* file

On master’s */etc/hosts*:

“`
1.1.1.1 ns1.example.com ns1
“`

On slave’s */etc/hosts*:

“`
2.2.2.2 ns2.example.com ns2
“`

### Installing BIND

**NOTE: all commands must be applied to both master and slave unless otherwise stated**

“`
apt-get -y install bind9 bind9utils
“`

Allow port 53:

“`
ufw allow 53
“`

### Configure the global options

Make the following changes in the */etc/bind/named.conf.options* of both servers:

“`
— /etc/bind/named.conf.options 2016-12-12 14:44:57.163515708 -0500
+++ /etc/bind/named.conf.options.new 2016-12-12 14:52:29.749268250 -0500
@@ -1,5 +1,7 @@
options {
directory “/var/cache/bind”;
+ recursion no;
+ allow-transfer { none; };

// If there is a firewall between you and nameservers you want
// to talk to, you may need to fix the firewall to allow multiple
“`

### Configure the local options

On master’s */etc/bind/named.conf.local*:

“`
— /etc/bind/named.conf.local 2016-12-12 20:06:27.000000000 +0000
+++ /etc/bind/named.conf.local.new 2016-12-12 20:07:03.000000000 +0000
@@ -6,3 +6,8 @@
// organization
//include “/etc/bind/zones.rfc1918”;

+zone “example.com” {
+ type master;
+ file “/etc/bind/db.example.com”;
+ allow-transfer { 2.2.2.2; };
+};
“`

On slave’s */etc/bind/named.conf.local*:

“`
— /etc/bind/named.conf.local 2016-11-01 13:02:24.000000000 -0400
+++ /etc/bind/named.conf.local.new 2016-12-12 15:09:47.445235343 -0500
@@ -6,3 +6,8 @@
// organization
//include “/etc/bind/zones.rfc1918”;

+zone “example.com” {
+ type slave;
+ file “db.example.com”;
+ masters { 1.1.1.1; };
+};
“`

### Create the zone file

On master server create the zone file (*/etc/bind/db.example.com*):

“`
$TTL 3600
@ IN SOA ns1.example.com. root.example.com. (
2016121201
7200
3600
1209600
180 )

; NS Records
@ 300 IN NS ns1.example.com.
@ 300 IN NS ns2.example.com.

; MX Records
@ 300 IN MX 10 mx1.example.com.
@ 300 IN MX 20 mx2.example.com.

; Address records
@ 300 IN A 3.3.3.3
ns1 300 IN A 1.1.1.1
ns2 300 IN A 2.2.2.2
mx1 300 IN A 4.4.4.4
mx1 300 IN A 5.5.5.5

; Alias (Canonical Name) records
www 300 IN CNAME example.com.
mail 300 IN CNAME mx1.example.com.
smtp 300 IN CNAME mx1.example.com.
imap 300 IN CNAME mx1.example.com.
pop 300 IN CNAME mx1.example.com.
webmail 300 IN CNAME mx1.example.com.

; TXT records
@ 300 IN TXT “v=spf1 a mx ?all”
“`

### Verify the global configuration

Run the `named-checkconf` command on both servers. If you get any errors you should fix them before proceeding.

### Verify the zone configuration

Run the following command on the master server:

“`
named-checkzone theo-andreou.org /etc/bind/db.example.com
zone example.com/IN: loaded serial 2016121201
OK
“`

If you get ‘OK’ then your setup is correct, otherwise you should fix it before proceeding.

### Restart bind and test your servers

“`
systemctl restart bind9.service
“`

Now test if your servers resolve your records.

The master:

“`
dig smtp.example.com @1.1.1.1

;; ANSWER SECTION:
smtp.example.com. 300 IN CNAME mx1.example.com.
mx1.example.com. 300 IN A 4.4.4.4

“`

The slave:

“`
dig smtp.example.com @2.2.2.2

;; ANSWER SECTION:
smtp.example.com. 300 IN CNAME mx1.example.com.
mx1.example.com. 300 IN A 4.4.4.4

“`

If you get any errors you can check your syslog file (*/var/log/syslog*).

## Finalizing

After you have tested that everything is OK, it is time to tell your registrar about the new servers. This is called *setting the [glue records](https://en.wikipedia.org/wiki/Domain_Name_System#Circular_dependencies_and_glue_records)* and you should consult the documentation of your registrar on how to do that. Ask support if you have any trouble.

References
———-
* https://www.digitalocean.com/community/tutorials/how-to-configure-bind-as-an-authoritative-only-dns-server-on-ubuntu-14-04

This guide is about setting up a Postfix/Dovecot system using LDAP/Fusiondirectoory as a backend.

### Prerequisites

* Install an [LDAP/Fusiondirectory infrastructure](/?p=1539)
* A DNS A Record:
“`
mail.example.com. 300 IN A 4.5.6.7
““
* A DNS PTR Record:
“`
7.6.5.4.in-addr.arpa. 300 IN PTR mail.example.com.
“`
* A DNS MX Record (Actually more than one):
“`
example.com. 300 IN MX 5 mail.example.com.
“`

### Install FusionDirectory Plugins

* Install the *Mail* plugin:

“`
apt -y install fusiondirectory-plugin-mail fusiondirectory-plugin-mail-schema
fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/mail-fd.schema
fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/mail-fd-conf.schema
“`

* Install the *Alias* plugin:

“`
apt -y install fusiondirectory-plugin-alias fusiondirectory-plugin-alias-schema
fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/alias-fd-conf.schema
fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/alias-fd.schema
“`

* Install the *Postfix* plugin:

“`
apt -y install fusiondirectory-plugin-postfix fusiondirectory-plugin-postfix-schema
fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/postfix-fd.schema
“`

### Setup mail services:

* Enter the *mail.example.com* server configuration (Systems plugin)

* From the ‘Services’ tab create a ‘Postfix (SMTP)’ and an ‘IMAP/POP3 generic’ service

* Add mail capability to all normal users:

* Click the ‘Mail’ tab of a user and then press ‘Add Mail settings’

* Fill in the ‘Primary Address. field and select *mail.example.com* as the server.

* Add All necessary distribution lists and redirections from ‘Aliases’

### Setup postfix

* Create a service account for *postfix* using the ‘DSA’ plugin in *FusionDirectory’. It should look like this:

“`
dn: cn=postfix,ou=dsa,dc=example,dc=com
cn: postfix
userPassword:: yeduyt2732tet87eoiewoi32t4873t4387f7gf47gf49i6=
structuralObjectClass: organizationalRole
entryUUID: 280427ce-9a54-1035-8e48-bf1fd814366b
creatorsName: cn=admin,dc=example,dc=com
createTimestamp: 20160419082627Z
objectClass: organizationalRole
objectClass: top
objectClass: simpleSecurityObject
entryCSN: 20160419082628.006263Z#000000#000#000000
modifiersName: cn=admin,dc=example,dc=com
modifyTimestamp: 20160419082628Z
“`

* Install postfix:

“`
apt -y install postfix postfix-pcre postfix-ldap
“`

When you are prompted about “General type of mail configuration:” select “No configuration”

* Prepare the */etc/postfix/main.cf* file:

“`
smtpd_banner = $myhostname ESMTP $mail_name
biff = no
append_dot_mydomain = no
readme_directory = no
smtpd_tls_cert_file=/etc/ssl/certs/mail.example.com.crt
smtpd_tls_key_file=/etc/ssl/private/mail.example.com.key
smtpd_use_tls=yes
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_tls_dh512_param_file = ${config_directory}/certs/dh_512.pem
smtpd_tls_dh1024_param_file = ${config_directory}/certs/dh_1024.pem
tls_random_source = dev:/dev/urandom
smtpd_tls_loglevel = 0
smtpd_client_new_tls_session_rate_limit = 10
smtpd_tls_exclude_ciphers =
EXP
EDH-RSA-DES-CBC-SHA
ADH-DES-CBC-SHA
DES-CBC-SHA
SEED-SHA
aNULL
eNULL
EXPORT
DES
RC4
MD5
PSK
aECDH
EDH-DSS-DES-CBC3-SHA
KRB5-DES-CBC3-SHA
myhostname = mail.example.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = $myhostname, mail.example.com, localhost.localdomain, localhost
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 10.10.10.0/24
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
local_transport = local
postscreen_greet_action = enforce
smtpd_recipient_restrictions =
reject
permit_mynetworks
permit_sasl_authenticated
warn_if_reject reject_non_fqdn_hostname
warn_if_reject reject_non_fqdn_sender
reject_invalid_hostname
reject_unknown_sender_domain
reject_unverified_recipient
reject_unauth_destination
reject_non_fqdn_sender
reject_non_fqdn_recipient
reject_non_fqdn_helo_hostname
check_sender_ns_access cidr:/etc/postfix/drop.cidr
check_sender_mx_access cidr:/etc/postfix/drop.cidr
reject_rbl_client bl.spamcop.net,
reject_rbl_client cbl.abuseat.org
reject
smtpd_data_restrictions = reject_multi_recipient_bounce
smtpd_sender_restrictions =
reject_non_fqdn_sender
reject_unknown_sender_domain
smtpd_helo_restrictions =
permit_mynetworks
check_helo_access pcre:/etc/postfix/identitycheck.pcre
reject_invalid_helo_hostname
disable_vrfy_command = yes
smtpd_helo_required = yes
smtpd_delay_reject = no
smtpd_client_restrictions = check_client_access cidr:/etc/postfix/drop.cidr
message_size_limit = 51200000
“`

* Prepare the rest of the configuration files:

* Prepare the virtual domains file:

cat > /etc/postfix/virtual_domains << EOF # Domain Anything example.com OK EOF * Prepare the virtual recipients file: cat > /etc/postfix/ldap_virtual_recipients.cf << EOF bind = yes bind_dn = cn=postfix,ou=dsa,dc=example,dc=com bind_pw = NotTheRealPassword server_host = ldap://ldap.example.com:389 search_base = ou=people,dc=example,dc=com domain = example.com query_filter = (mail=%s) result_attribute = mail start_tls = yes version = 3 EOF * Prepare the virtual aliases file: ``` cat > /etc/postfix/ldap_virtual_aliases.cf << EOF bind = yes bind_dn = cn=postfix,ou=dsa,dc=example,dc=com bind_pw = NotTheRealPass server_host = ldap://ldap.example.com:389 search_base = ou=alias,dc=example,dc=com domain = example.com query_filter = (mail=%s) result_attribute = gosaMailAlternateAddress, gosaMailForwardingAddress start_tls = yes version = 3 EOF ``` * Prepare the identity check file: cat > /etc/postfix/identitycheck.pcre << EOF # Identity (RegEx) Action /^(mail\.example\.com)$/ REJECT Hostname Abuse: $1 /^(1\.2\.3\.4)$/ REJECT Hostname Abuse: $1 /^(\[1\.2\.3\.4\])$/ REJECT Hostname Abuse: $1 EOF * Prepare the blacklist file: cat > /etc/postfix/drop.cidr << EOF # IP/CIDR Action 1.2.3.0/24 REJECT Blacklisted EOF * Generate the virtual domains hashmap: postmap hash:/etc/postfix/virtual_domains * Start postfix: systemctl start postfix Verify:

    ss -lnptu | grep master
    tcp    LISTEN     0      100    *:25      *:*      users ((“master”,pid=15539,fd=12))
    

* Enable support for smtps (port 465) and submission (port 587):

Uncomment the following lines from */etc/postfix/master.cf*:

submission inet n – – – – smtpd
smtps inet n – – – – smtpd

Restart postfix:

systemctl restart postfix

Verify:

    ss -lnptu | grep master
    tcp    LISTEN     0      100    *:587     *:*      users:(("master",pid=15854,fd=16))
    tcp    LISTEN     0      100    *:465     *:*      users:(("master",pid=15854,fd=19))
    tcp    LISTEN     0      100    *:25      *:*      users:(("master",pid=15854,fd=12))
    

* Take precautions for perfect forward secrecy:

“`
mkdir /etc/postfix/certs
cd /etc/postfix/certs
openssl dhparam -2 -out dh_512.pem 512
openssl dhparam -2 -out dh_1024.pem 1024
chmod 600 dh_*
“`

* Lookup test:

    postmap -q theo@example.com ldap:/etc/postfix/ldap_virtual_recipients.cf
    theo@example.com
    

* Open SMTP, SMTPS ans Submission ports:

“`
ufw allow 25/tcp
ufw allow 465/tcp
ufw allow 587/tcp
“`

### Install and configure dovecot

* Create the user that will handle mail delivery:

“`

“`

* Create a service account for *dovecot* using the ‘DSA’ plugin in *FusionDirectory’. It should look like this:

“`
dn: cn=dovecot,ou=dsa,dc=example,dc=com
cn: dovecot
userPassword:: ljsdewd98dej932j98dxjud8x3jx9843xj8943j438439e3=
structuralObjectClass: organizationalRole
entryUUID: 4d0d7174-9a54-1035-8e49-bf1fd814366b
creatorsName: cn=admin,dc=example,dc=com
createTimestamp: 20160419082730Z
objectClass: organizationalRole
objectClass: top
objectClass: simpleSecurityObject
entryCSN: 20160419082730.138012Z#000000#000#000000
modifiersName: cn=admin,dc=example,dc=com
modifyTimestamp: 20160419082730Z
“`

* Install dovecot:

apt -y install dovecot-core dovecot-imapd dovecot-pop3d dovecot-lmtpd dovecot-ldap

* Make the following changes in */etc/dovecot/conf.d/10-ssl.conf*:

ssl = required
ssl_cert = service imap-login { inet_listener imap { port = 143 } inet_listener imaps { port = 993 ssl = yes } }
service pop3-login { inet_listener pop3 { port = 110 } inet_listener pop3s { port = 995 ssl = yes } }
service auth { unix_listener auth-userdb { mode = 0777 user = dovecot group = dovecot } }

* Add the *vmail* user in the system:

addgroup –system –gid 5000 vmail
adduser –system –home /srv/vmail –uid 5000 –gid 5000 –disabled-password –disabled-login vmail

* Restart *dovecot*:

systemctl restart dovecot

Verify:

    netstat -lnptu | grep dovecot
    tcp        0      0 0.0.0.0:993             0.0.0.0:*               LISTEN      20894/dovecot   
    tcp        0      0 0.0.0.0:995             0.0.0.0:*               LISTEN      20894/dovecot   
    tcp        0      0 0.0.0.0:110             0.0.0.0:*               LISTEN      20894/dovecot   
    tcp        0      0 0.0.0.0:143             0.0.0.0:*               LISTEN      20894/dovecot   
    tcp6       0      0 :::993                  :::*                    LISTEN      20894/dovecot   
    tcp6       0      0 :::995                  :::*                    LISTEN      20894/dovecot   
    tcp6       0      0 :::110                  :::*                    LISTEN      20894/dovecot   
    tcp6       0      0 :::143                  :::*                    LISTEN      20894/dovecot  
    

* Check if you can login:

openssl s_client -connect localhost:993

* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN AUTH=LOGIN] Dovecot ready.
a1 LOGIN theo MyNotSoSecretPass
a1 OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE BINARY MOVE] Logged in
a3 LOGOUT
* BYE Logging out
a2 OK Logout completed.
closed

* Enable IMAP, IMAPS, POP3 and POP3S ports:

“`
ufw allow 110/tcp
ufw allow 143/tcp
ufw allow 993/tcp
ufw allow 995/tcp
“`

* Tell *postfix* to deliver mail using *dovecot*:

* Add the following lines at the end of */etc/postfix/master.cf*:

dovecot   unix  -       n       n       -       -       pipe
  flags=ODRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -e -f ${sender} -d ${recipient}
        

* Add these attributes in */etc/postfix/main.cf*:

“`
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1
“`

* Restart postfix and dovecot:

systemctl restart postfix dovecot

### Install SASL for SMTP AUTH

* Create a service account for *saslauthd* using the ‘DSA’ plugin in *FusionDirectory’. It should look like this:

“`
dn: cn=saslauthd,ou=dsa,dc=example,dc=com
cn: saslauthd
userPassword:: ejdoedoifj9ewufd9843e9ejfd98je938jcr9843843=
structuralObjectClass: organizationalRole
entryUUID: 61143234-9a54-1035-8e4a-bf1fd814366b
creatorsName: cn=admin,dc=example,dc=com
createTimestamp: 20160419082803Z
objectClass: organizationalRole
objectClass: top
objectClass: simpleSecurityObject
entryCSN: 20160419082803.738357Z#000000#000#000000
modifiersName: cn=admin,dc=example,dc=com
modifyTimestamp: 20160419082803Z
“`

* Install *SASL*:

“`
apt -y install libsasl2-2 sasl2-bin
“`
* Create the */etc/postfix/sasl/smtpd.conf* file:

“`
cat > /etc/postfix/sasl/smtpd.conf << EOF log_level: 3 pwcheck_method: saslauthd mech_list: PLAIN LOGIN EOF ``` * Make the following changes in */etc/default/saslauthd*: ``` START=yes MECHANISMS="ldap" OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd" ``` * Create the */etc/saslauthd.conf* file: ``` cat > /etc/saslauthd.conf << EOF ldap_servers: ldap://ldap.example.com/ ldap_bind_dn: cn=saslauthd,ou=dsa,dc=example,dc=com ldap_bind_pw: MySecretPass ldap_timeout: 10 ldap_time_limit: 10 ldap_scope: sub ldap_search_base: ou=people,dc=example,dc=com ldap_auth_method: bind ldap_filter: (&(uid=%u)(mail=*)) ldap_debug: 0 ldap_verbose: off ldap_ssl: yes ldap_starttls: no ldap_referrals: yes EOF ``` * Add the *postfix* user in the *sasl* group: ``` usermod -aG sasl postfix ``` * Add these attributes in */etc/postfix/main.cf*: ``` smtpd_sasl_auth_enable = yes broken_sasl_auth_clients = yes ``` * Restart *saslauthd* and *postfix*: ``` systemctl restart saslauthd postfix ``` * Test message delivery using SMTP AUTH: First you need to install *swaks*: apt -y install swaks Then use *swaks* to test message delivery: swaks --from noreply@example.com --to theo@example.com --server 127.0.0.1:25 --tls --auth plain --auth-user=theo * Test if the message has been delivered to inbox: First you need to install *mutt*: apt -y install mutt Then use *mutt* to test if the message has been delivered to inbox: mutt -f /srv/vmail/theo@example.com/Maildir/ __NOTE: When you are asked to create a 'mail' folder just say 'no'.__ References ---------- * https://documentation.fusiondirectory.org/en/documentation/plugin/mail_plugin * https://documentation.fusiondirectory.org/en/documentation/plugin/alias_plugin * https://documentation.fusiondirectory.org/en/documentation/plugin/dovecot_plugin

# LDAP/Fusiondirectory setup

In this guide we will be setting up LDAP ([openldap](http://www.openldap.org/)) along with the [FusionDirectory](https://www.fusiondirectory.org/) web management tool.

### Preparations

* Install Debian jessie (Ubuntu 16.04 should work too) on your server or VM

* Setup the DNS records in your DNS servers:

“`
ldap.example.com. 3599 IN A 1.1.1.1
“`

**NOTE: replace 1.1.1.1 with you actual internal or external IP**

* Allow ssh and web services on firewall:

“`
apt -y install ufw
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable
“`

**NOTE: It may be a good idea to change the default ssh port from 22 to something less predictable**

### Setup LDAP

* Setup *ldap.example.com* in */etc/hosts*:

“`
127.0.2.1 ldap.example.com ldap
“`

* Install **OpenLDAP* and *FusionDirectory*

“`
apt -y install slapd
“`

* Enter and verify the administrator password for *slapd*.

* Create An Internal Certificate Authority for Example LTD:

* First install *gnutls-bin*:

“`
apt -y install gnutls-bin
“`

* Create the key for the internal CA for *example.com*:

“`
certtool –generate-privkey –outfile example.com-rootCA.key
“`

* Create a certificate for our internal CA:

certtool --generate-self-signed --load-privkey example.com-rootCA.key --outfile example.com-rootCA.crt
Generating a self signed certificate...
Please enter the details of the certificate's distinguished name. Just press enter to ignore a field.
Common name: Example LTD Internal ROOT CA
UID: 
Organizational unit name: IT
Organization name: Example LTD
Locality name: Limassol
State or province name: Limassol
Country name (2 chars): CY
Enter the subject's domain component (DC): 
This field should not be used in new certificates.
E-mail: admins@example.com
Enter the certificate's serial number in decimal (default: 6295758616856773074): 
The certificate will expire in (days): 7300

Activation/Expiration time. The certificate will expire in (days): 7300

Extensions. Does the certificate belong to an authority? (y/N): y Path length constraint (decimal, -1 for no constraint): -1 Is this a TLS web client certificate? (y/N): Will the certificate be used for IPsec IKE operations? (y/N): Is this a TLS web server certificate? (y/N): Enter a dnsName of the subject of the certificate: Enter a URI of the subject of the certificate: Enter the IP address of the subject of the certificate: Enter the e-mail of the subject of the certificate: Will the certificate be used to sign other certificates? (y/N): y Will the certificate be used to sign CRLs? (y/N): Will the certificate be used to sign code? (y/N): Will the certificate be used to sign OCSP requests? (y/N): Will the certificate be used for time stamping? (y/N): Enter the URI of the CRL distribution point: X.509 Certificate Information: Version: 3 Serial Number (hex): 575f071b0d5a41d2 Validity: Not Before: Mon Jun 13 19:19:27 UTC 2016 Not After: Sun Jun 08 19:20:00 UTC 2036 Subject: CN=Example LTD Internal ROOT CA,OU=IT,O=Example LTD,L=Limassol,ST=Limassol,C=CY,EMAIL=admins@example.com Subject Public Key Algorithm: RSA Algorithm Security Level: Medium (2048 bits) Modulus (bits 2048): 00:c0:75:c8:02:05:d0:0c:67:af:ac:0c:80:53:bf:cd a3:80:76:cf:3e:14:19:99:5c:24:b4:fc:b0:42:8d:5a 03:5d:04:a5:85:c7:fe:e3:d4:30:6c:4c:26:90:76:c5 3e:a0:dc:a7:53:a7:eb:13:60:78:44:b3:0a:b2:77:0c 46:19:96:ea:d2:46:82:9c:11:2c:a5:e2:a1:57:38:f4 8e:4d:74:4f:f9:41:dd:11:f4:c2:f5:9f:b7:9a:93:7d a7:f8:f3:dd:2e:08:6a:25:75:79:f3:63:e5:09:1f:bd 6a:38:45:85:f0:63:54:c0:08:68:41:15:66:a4:e3:84 49:7e:e5:c5:c7:6c:d3:c7:be:d5:5a:df:1a:1d:55:f8 35:73:bb:e3:ea:f7:66:af:d9:09:72:ca:17:5f:80:09 99:6a:49:e3:8b:f2:72:56:ac:f8:ba:60:49:d5:80:2a 07:e6:17:88:86:e4:3c:89:cd:af:2b:66:a1:af:53:f4 66:21:30:a3:22:af:a9:11:6e:98:e0:f7:6d:ef:8a:32 e9:0b:a4:82:7b:7b:db:2d:90:8e:bd:e4:54:04:a4:52 e8:cf:f6:2e:9b:97:46:ab:cb:38:06:23:33:db:42:0c 25:41:5a:d7:02:15:07:c6:e8:86:0b:a6:d7:7d:81:16 bd Exponent (bits 24): 01:00:01 Extensions: Basic Constraints (critical): Certificate Authority (CA): TRUE Key Purpose (not critical): Time stamping. Key Usage (critical): Certificate signing. Subject Key Identifier (not critical): 7a596f6dea4080e89c9e78a698d7126cd63dafa7 Other Information: Public Key ID: 7a596f6dea4080e89c9e78a698d7126cd63dafa7 Public key's random art: +--[ RSA 2048]----+ | | | . . | | . . . | | o . . | | . .+. S o | | =o..o. + . . | | o.o= .oo . o o | | oo+. .o o o | |o... E+ .o | +-----------------+

Is the above information ok? (y/N): y

Signing certificate...

* Add the *Example LTD Internal ROOT CA* as trusted in *ca-certificates*:

“`
mkdir /usr/share/ca-certificates/extra
cp example.com-rootCA.crt /usr/share/ca-certificates/extra
dpkg-reconfigure ca-certificates
“`

Add the *extra/example.com-rootCA.crt* CA as a trusted CA.

* Configure *slapd*:

“`
dpkg-reconfigure slapd
“`
* Omit OpenLDAP server configuration? **No**
* DNS domain name: **example.com**
* Organization name: **Example LTD**
* Administrator password: ***************
* Verify password: *************
* Database backend to use: **MDB**
* Do you want the database to be removed when slapd is purged? **No**
* Move old database? **Yes**
* Allow LDAPv2 protocol? **No**

* Configure TLS on LDAP:

* Create a key for *ldap.example.com*:

“`
certtool –generate-privkey –outfile ldap.example.com.key
Generating a 2048 bit RSA private key…
“`

* Create a certificate for *ldap.example.com*:

certtool --generate-certificate --load-privkey ldap.example.com.key --outfile ldap.example.com.crt --load-ca-certificate example.com-rootCA.crt --load-ca-privkey example.com-rootCA.key
Generating a signed certificate...
Please enter the details of the certificate's distinguished name. Just press enter to ignore a field.
Common name: ldap.example.com
UID: 
Organizational unit name: IT
Organization name: Example LTD
Locality name: Limassol
State or province name: Limassol
Country name (2 chars): CY
Enter the subject's domain component (DC): 
This field should not be used in new certificates.
E-mail: admins@example.com
Enter the certificate's serial number in decimal (default: 6295762607454361711):

Activation/Expiration time. The certificate will expire in (days): 3650

Extensions. Does the certificate belong to an authority? (y/N): Is this a TLS web client certificate? (y/N): Will the certificate be used for IPsec IKE operations? (y/N): Is this a TLS web server certificate? (y/N): Enter a dnsName of the subject of the certificate: Enter a URI of the subject of the certificate: Enter the IP address of the subject of the certificate: Enter the e-mail of the subject of the certificate: Will the certificate be used for signing (required for TLS)? (Y/n): Will the certificate be used for encryption (not required for TLS)? (Y/n): X.509 Certificate Information: Version: 3 Serial Number (hex): 575f0abc2f81186f Validity: Not Before: Mon Jun 13 19:35:45 UTC 2016 Not After: Thu Jun 11 19:36:29 UTC 2026 Subject: CN=ldap.example.com,OU=IT,O=Example LTD,L=Limassol,ST=Limassol,C=CY,EMAIL=admins@example.com Subject Public Key Algorithm: RSA Algorithm Security Level: Medium (2048 bits) Modulus (bits 2048): 00:d0:15:8e:02:90:5f:4a:9f:90:ea:1e:35:e6:4b:eb a9:8c:e5:bf:68:ec:83:0e:49:5b:d1:f0:08:4b:ac:b0 31:d2:e0:a7:eb:18:d3:ee:b8:38:b7:c4:0a:cc:97:cc b6:ac:2d:29:c8:a8:c4:7c:cc:f1:36:5a:e9:6b:52:f5 1e:e5:4f:90:67:34:1f:8c:a8:17:72:ee:40:87:ba:ae 8b:f8:4f:f8:be:51:ee:ea:d5:e4:17:63:79:22:41:c0 19:43:33:55:bb:46:80:5c:b8:16:18:fa:fb:17:58:c2 ed:d2:14:10:3b:57:5d:de:7f:29:ab:66:c2:81:87:05 f7:b7:27:78:a9:c0:8e:4f:1c:3f:66:6f:dd:43:26:9f 84:59:fb:c7:21:3c:62:4f:8d:4a:25:ab:7e:f0:5f:7e df:97:f7:79:f8:c7:2d:c8:5a:7a:de:ea:5b:c7:bd:e9 12:17:56:d3:47:ff:eb:fa:b5:6f:d9:56:8f:c7:e8:7a 46:92:75:cc:ff:de:0e:88:49:7d:d7:dd:6e:8d:3f:57 fa:0a:7a:3b:80:ec:0e:10:dd:70:d5:9a:8d:91:ce:72 44:06:21:d2:9d:e9:b8:91:13:68:4c:fc:e2:bb:4d:a8 97:ed:e9:a4:98:5d:e7:c0:ef:3e:9d:30:28:de:bd:10 01 Exponent (bits 24): 01:00:01 Extensions: Basic Constraints (critical): Certificate Authority (CA): FALSE Key Usage (critical): Digital signature. Key encipherment. Subject Key Identifier (not critical): 6d8a173de01efa11a892dda76ccd7abc609a2707 Authority Key Identifier (not critical): 7a596f6dea408aa89c9e78a698d7126cd63dafa7 Other Information: Public Key ID: 6d8a173de01efa00a892dda67ccd7abc609a2707 Public key's random art: +--[ RSA 2048]----+ | | | | | . | | . + | | A = | | +Y= . | | oo+kk+ | | iii==o* | | .=B**o. | +-----------------+

Is the above information ok? (y/N): y

Signing certificate...

* Enable LDAPS in */etc/default/slapd*:

        SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"
        

* Copy the *ldap.example.com* certficate and apply permissions

“`
mkdir /etc/ldap/ssl
cp ldap.example.com.crt /etc/ldap/ssl
cp ldap.example.com.key /etc/ldap/ssl
chown -R openldap:openldap /etc/ldap/ssl/
“`

* Create a *olcSSL.ldif* file:

mkdir /etc/ldap/custom_ldifs/
cd /etc/ldap/custom_ldifs/
cat > olcSSL.ldif << EOF dn: cn=config changetype: modify add: olcTLSCACertificateFile olcTLSCACertificateFile: /etc/ssl/certs/ca-certificates.crt - add: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/ldap/ssl/ldap.example.com.key - add: olcTLSCertificateFile olcTLSCertificateFile: /etc/ldap/ssl/ldap.example.com.crt EOF

* Import the TLS configuration:

“`
ldapmodify -Y EXTERNAL -H ldapi:/// -f olcSSL.ldif
“`

Verify with:

slapcat -n0 | grep -i tls
olcTLSCACertificateFile: /etc/ssl/certs/ca-certificates.crt
olcTLSCertificateFile: /etc/ldap/ssl/ldap.example.com.crt
olcTLSCertificateKeyFile: /etc/ldap/ssl/ldap.example.com.key
        

* Restart and verify *slapd*:

systemctl restart slapd
netstat -lnptu | grep slapd
tcp        0      0 0.0.0.0:636             0.0.0.0:*               LISTEN      27665/slapd     
tcp        0      0 0.0.0.0:389             0.0.0.0:*               LISTEN      27665/slapd     
tcp6       0      0 :::636                  :::*                    LISTEN      27665/slapd     
tcp6       0      0 :::389                  :::*                    LISTEN      27665/slapd 
        

### Setup *Apache*

* Install *Apache* with *PHP*:

“`
apt -y install apache2 libapache2-mod-php5 php5-ldap php5-mcrypt php5-intl php-pear
“`

### Setup *Let’s Encrypt*:

**NOTE: this step is only necessary if you have a public facing *ldap.example.com* service**

* Setup Debian jessie backports:

“`
cat >> /etc/apt/sources.list << EOF # jessie backports deb http://ftp.debian.org/debian jessie-backports main deb-src http://ftp.debian.org/debian jessie-backports main EOF ``` * Run `apt update` * Install *Let's Encrypt* utility, *certbot*: ``` apt -y install python-certbot-apache -t jessie-backports ``` * Generate a certificate for all the domain *ldap.example.com*: ``` certbot run -d ldap.example.com ``` In the TUI add the *admins@example.com* email and agree to the ToS. Use 000-default.conf for now. * Download and trust all *Let's Encrypt* Root and Intermediate CA certificates: ``` wget https://letsencrypt.org/certs/isrgrootx1.pem for i in {1..4}; do wget https://letsencrypt.org/certs/lets-encrypt-x$i-cross-signed.pem; done cp *.pem /usr/share/ca-certificates/extra/ for f in *.pem; do cp -- "$f" "/usr/share/ca-certificates/extra/${f%.pem}.crt"; done dpkg-reconfigure ca-certificates # Select all the newlly added CA certs ``` ### Setup FusionDirectory * Setup Fusiondirectory Repo: ``` gpg --keyserver keys.gnupg.net --recv-key 62B4981F gpg --export -a "Fusiondirectory Archive Manager ” > FD-archive-key
apt-key add FD-archive-key
echo ‘# fusiondirectory repository’ > /etc/apt/sources.list.d/fusiondirectory.list
echo ‘deb http://repos.fusiondirectory.org/debian-jessie jessie main’ >> /etc/apt/sources.list.d/fusiondirectory.list
echo ‘deb-src http://repos.fusiondirectory.org/debian-jessie jessie main’ >> /etc/apt/sources.list.d/fusiondirectory.list
apt update
“`

* Install *FusionDirectory*:

“`
apt -y install fusiondirectory fusiondirectory-schema
“`

* Insert core *FusionDirectory* schemas into *slapd

“`
fusiondirectory-insert-schema
“`

Verify:

fusiondirectory-insert-schema -l
core
cosine
nis
inetorgperson
samba
core-fd
core-fd-conf
ldapns
recovery-fd
   

* Create a Fusiondirectory Apache vhost (*/etc/apache2/sites-available/ldap.example.com.conf*):

“`

ServerName ldap.example.com
Redirect “/” “https://ldap.example.com/”
ErrorLog ${APACHE_LOG_DIR}/ldap-error.log
CustomLog ${APACHE_LOG_DIR}/ldap-access.log combined



ServerName ldap.example.com
ServerAdmin webmaster@example.com
DocumentRoot /usr/share/fusiondirectory/html
ErrorLog ${APACHE_LOG_DIR}/ldap-error.log
CustomLog ${APACHE_LOG_DIR}/ldap-access.log combined
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/ldap.example.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/ldap.example.com/privkey.pem

SSLOptions +StdEnvVars


SSLOptions +StdEnvVars

BrowserMatch “MSIE [2-6]” \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
BrowserMatch “MSIE [17-9]” ssl-unclean-shutdown


php_admin_flag engine on
php_admin_flag register_globals off
php_admin_flag allow_call_time_pass_reference off
php_admin_flag expose_php off
php_admin_flag zend.ze1_compatibility_mode off
php_admin_flag register_long_arrays off
php_admin_value upload_tmp_dir /var/spool/fusiondirectory/
php_admin_value session.cookie_lifetime 0
#Include /etc/fusiondirectory/fusiondirectory.secrets



Order Allow,Deny
# Insert your public IPs here
Allow from 2.2.2.2
Allow from 2.2.2.3



“`

* Enable *mod_ssl*, *ldap.example.com* and disable *000-default* and *default-ssl*:

“`
a2enmod ssl
a2ensite ldap.example.com
a2dissite default-ssl
a2dissite 000-default
systemctl restart apache2
“`

* Setup *FusionDirectory*:

* Install optional prerequisities:

“`
apt -y install php-mdb2
“`

* Point your Browser to:

“`
https://ldap.example.com/
“`

* Create a temporary token for the setup (taken from the first setup webpage):

“`
echo -n r9l1srnu0rvdeca4k826nq4e05 > /var/cache/fusiondirectory/fusiondirectory.auth
“`

Click ‘Next’

* In the ‘Language setup’ select ‘English’ and press ‘Next’.

* If everything is ‘OK'(Green) on the ‘Installation check’ click ‘Next’

* On the ‘LDAP connection setup’:
* Location name: **default**
* Connection URI: **ldap://ldap.example.com:389**
* TLS connection: **Yes**
* Admin DN: **cn=admin**(,dc=example,dc=com)
* Admin password: *************************
* LDAP schema check:
* Enable schema validation when logging in: **Yes**

* Keep defaults in ‘Look and feel’ except ‘Timezone’:

* Timezone: **America/Los_Angeles**

* Keep all the defaults in ‘Password settings’ except this:

* Password minimum length: **8**

* In the ‘SSL’ field use these:
* Key path: **/etc/ldap/ssl/ldap.example.com.key**
* Certificate path: **/etc/ldap/ssl/ldap.example.com.crt**
* CA certificate path: **/etc/ssl/certs/ca-certificates.crt**

Click ‘Next’ when done.

* In the ‘LDAP inspection’ page:
* Press ‘Migrate’ (twice) in the ‘Inspecting object classes in root object’ option

* Press ‘Create’ in the ‘Checking for super administrator’ option’, fill the fields, and ‘Apply’ when done:
* User ID: **ldapadmin**
* Password: ***************
* Password (again): ***************

* In the ‘Checking for default ACL roles and groups’ field, press ‘Migrate’

* From the ‘Finish – write the configuration file’, download the configuration file on your PC

* Copy the configuration file from your PC to ldap.example.com:

“`
scp fusiondirectory.conf root@ldap.example.com:/etc/fusiondirectory
“`

* Apply the correct permissions to the */etc/fusiondirectory/fusiondirectory.conf* file:

fusiondirectory-setup --check-config
Checking FusionDirectory's config file
/etc/fusiondirectory/fusiondirectory.conf exists…
/etc/fusiondirectory/fusiondirectory.conf is not set properly, do you want to fix it ?:  [Yes/No]?
y
        

* Click ‘Next’ when done.

* Use encrypted passwords in *fusiondirectory.conf*:

* Enable the *headers* module in *Apache*:

“`
a2enmod headers
systemctl restart apache2
“`

* Encrypt passwords in *fusiondirectory.conf*:

“`
fusiondirectory-setup –encrypt-passwords
“`

* Uncomment the following line in */etc/apache2/sites-available/ldap.example.com.conf*:

“`
Include /etc/fusiondirectory/fusiondirectory.secrets
“`

* Restart *Apache*:

“`
systemctl restart apache2
“`

* If everything works as expected remove */etc/fusiondirectory/fusiondirectory.conf.orig*

“`
rm /etc/fusiondirectory/fusiondirectory.conf.orig
“`

* Allow ‘.’ (dot) in usernames:

* After everything is set, login as *ldapadmin*
* Go to ‘Configuration’
* Press the ‘Edit’ button at the bottom of the page
* Un-tick the ‘Strict naming policy’ option and save.

### Installing essential FusionDirectory plugins

* Setup *LDAP* related plugins:

“`
apt -y install fusiondirectory-plugin-ldapdump fusiondirectory-plugin-ldapmanager
“`

* Setup the *DSA* plugin for managing service accounts:

“`
apt -y install fusiondirectory-plugin-dsa fusiondirectory-plugin-dsa-schema
fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/dsa-fd-conf.schema
“`

* Allow the service accounts to read and write the password. First create the *ACL* definition:

cat > /etc/ldap/custom_ldifs/service_accounts_acl.ldif << EOF
dn: olcDatabase={1}mdb,cn=config
changetype: modify
delete: olcAccess
-
add: olcAccess
olcAccess: {0}to dn.subtree="dc=example,dc=com" attrs=userPassword
  by self write
  by dn.base="cn=admin,dc=example,dc=com" write
  by dn.children="ou=dsa,dc=example,dc=com" write
  by anonymous auth
  by * none
-
add: olcAccess
olcAccess: {1}to dn.subtree="ou=people,dc=example,dc=com"
  by self read
  by dn.base="uid=test.user,ou=people,dc=example,dc=com" write
  by dn.base="cn=admin,dc=example,dc=com" write
  by dn.children="ou=dsa,dc=example,dc=com" read
  by anonymous auth
  by * none
-
add: olcAccess
olcAccess: {2}to attrs=userPassword,shadowLastChange
  by self write
  by anonymous auth
  by dn="cn=admin,dc=example,dc=com" write
  by * none
-
add: olcAccess
olcAccess: {3}to dn.subtree="dc=example,dc=com"
  by self read
  by dn.base="cn=admin,dc=example,dc=com" write
  by dn.children="ou=dsa,dc=example,dc=com" write
  by * none
-
add: olcAccess
olcAccess: {4}to dn.base=""
  by * none
EOF
        

**NOTE: Add two spaces before each ‘*by*’ in the ldif above or you will spend endless hours in troubleshooting!**

* Apply the ACL

“`
ldapadd -c -Y EXTERNAL -H ldapi:/// -f /etc/ldap/custom_ldifs/service_accounts_acl.ldif
“`

* Setup the *Systems* plugin:

“`
apt -y install fusiondirectory-plugin-systems fusiondirectory-plugin-systems-schema
fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/service-fd.schema
fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/systems-fd-conf.schema
fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/systems-fd.schema
“`

* Setup a new server:

* Name: **ldap.example.com**
* Description: **Communications Server**
* Location: **My Datacenter**
* Base: **/**

* IP-address: **10.134.31.94**
* MAC-address: **04:01:05:d6:63:02**

* From the ‘Services’ tab setup an *LDAP* service on the *ldap.example.com* server

You are finished. You can now start connecting services to your LDAP setup like [mail](https://documentation.fusiondirectory.org/en/documentation/plugin/mail_plugin) or [asterisk](https://documentation.fusiondirectory.org/en/documentation/plugin/asterisk_plugin/asterisk_and_fusiondirectory).

References
———-
* https://documentation.fusiondirectory.org/en/start

I have been using [Skelleton](https://www.skelleton.net)’s guide[^guide] to setup [opendmarc](http://www.trusteddomain.org/opendmarc/) on some mail server I am building.

My problem is the version of opendmarc that comes with Debian is 1.3.0 and this version has a bug[^list] which fails to honor the *IgnoreAuthenticatedClients* directive.

This is an attempt to build[^build] the newest version, 1.3.1, for Debian jessie.

### Prepare the environment

* Install all necessary packages:

“`
$ sudo apt -y install pbuilder debootstrap devscripts packaging-dev debian-keyring
“`

* Prepare a Debian jessie build environment:

“`
$ sudo pbuilder create –debootstrapopts –variant=buildd –mirror http://ftp.us.debian.org/debian/ –distribution jessie –architecture amd64 –components main –debbuildopts -mJohn Doe \
“`

### Prepare the Debian environment for *opendmarc* 1.3.1

* Download and extract the package:

“`
$ wget http://downloads.sourceforge.net/project/opendmarc/opendmarc-1.3.1.tar.gz
$ tar xvzf opendmarc-1.3.1.tar.gz
$ cd opendmarc-1.3.1/
“`
* Prepare for Debian packaging:

“`
$ DEBFULLNAME=”John Doe” DEBEMAIL=”john.doe@example.net” dh_make -s -y –createorig
“`

* Rename the *debian* folder:

“`
$ mv debian debian.orig
“`

* Shamelessly copy *debian/** from the original:

“`
$ cd /tmp/
$ apt-get source opendmarc
$ cd opendmarc-1.3.1+dfsg/
$ cp -a debian/ ~/opendmarc-1.3.1
“`

* Optional steps:

* Change the Author name to yours in *debian/control*

* Restore the *debian/changelog* file:

“`
$ cp debian.orig/changelog debian/
“`

* Get rid of the *debian.orig* folder:

“`
$ mv debian.orig/ ..
“`

* Edit the *debian/changelog* file with `dch -e`:

opendmarc (1.3.1-1) unstable; urgency=medium
  * Initial release: To fix the IgnoreAuthenticatedClients issue:     http://www.trusteddomain.org/pipermail/opendmarc-users/2016-April/000636.html
 -- John Doe <john.doe@example.net> Fri, 29 Apr 2016 13:43:22 +0300

### Build *opendmarc* 1.3.1

* Run *pdebuild*:

“`
$ pdebuild
“`

* You cab find the resultant debs under */var/cache/pbuilder/result/*:

“`
$ ls -la /var/cache/pbuilder/result/
total 868
drwxr-xr-x 2 root root 4096 Απρ 29 13:54 .
drwxr-xr-x 8 root root 4096 Απρ 29 12:56 ..
-rw-r–r– 1 theodotos theodotos 38534 Απρ 29 13:54 libopendmarc2_1.3.1-1_amd64.deb
-rw-r–r– 1 theodotos theodotos 64210 Απρ 29 13:54 libopendmarc-dev_1.3.1-1_amd64.deb
-rw-r–r– 1 theodotos theodotos 2348 Απρ 29 13:54 opendmarc_1.3.1-1_amd64.changes
-rw-r–r– 1 theodotos theodotos 75890 Απρ 29 13:54 opendmarc_1.3.1-1_amd64.deb
-rw-rw-r– 1 theodotos theodotos 846 Απρ 29 13:54 opendmarc_1.3.1-1.dsc
-rw-r–r– 1 theodotos theodotos 663859 Απρ 29 13:54 opendmarc_1.3.1-1.tar.gz
-rw-r–r– 1 theodotos theodotos 17136 Απρ 29 13:54 rddmarc_1.3.1-1_all.deb
“`

You can now copy the debs over your mail server and test them.

__Update: I did this before I had discovered that opendmarc 1.3.1 is in Debian jessie backports[^backports]. But an interesting drill nevertheless.__

References
———-
[^guide]: https://www.skelleton.net/2015/03/21/how-to-eliminate-spam-and-protect-your-name-with-dmarc/
[^list]: http://www.trusteddomain.org/pipermail/opendmarc-users/2016-April/000636.html
[^build]: http://www.theo-andreou.org/?p=1145
[^backports]: http://www.trusteddomain.org/pipermail/opendmarc-users/2016-April/000641.html

This is a guide to setup a recent Ubuntu system on a Utilite ARM computer, to replace the official Ubuntu 12.04 OS.

Prerequisites
————-

* You need to prepare a [kernel with cgroups](/?p=1073 “Building a new Linux kernel for your Utilite Computer”) support.
* An ARM bootable microSD or USB. You can use the official Ubuntu 12.04 [Linux Utilite Image](http://www.compulab.co.il/utilite-computer/wiki/index.php/Utilite_Linux_Image “Linux Utilite Image”) on the removable device.
* Backup any data you have on the original system!

Preparations
————

1. Boot from microSD or USB.

2. Update the system and install **`debootstrap`**:

   $ sudo apt-get update
   $ sudo apt-get install debootstrap
   

3. Mount the SATA root filesystem on ***/mnt***:

   $ sudo mount /dev/sda2 /mnt
   

4. Clear the filesystem:

> ***Note***
> *Make sure you save any data you need, before doing this!.*

   $ sudo rm -fr /mnt/*
   

Installation of an Ubuntu or Debian base system
———————————————–

1. Use **`debootstrap`** to install the Ubuntu base system:

   $ sudo debootstrap --foreign --arch=armhf trusty /mnt http://ports.ubuntu.com/
   

You can use **vivid** instead of **trusty** if you are feeling adventurous.

For a Debian system use this command instead:

   $ sudo debootstrap --foreign --arch armhf jessie /mnt http://ftp.uk.debian.org/debian
   

You can use **stretch** or **sid** instead of **jessie** if you are feeling lucky.

2. Chroot into the new system:

   $ sudo mount -o bind /dev /mnt/dev
   $ sudo mount -o bind /dev/pts /mnt/dev/pts
   $ sudo mount -t sysfs /sys /mnt/sys
   $ sudo mount -t proc /proc /mnt/proc
   $ sudo cp /proc/mounts /mnt/etc/mtab
   $ sudo chroot /mnt
   

3. Second stage **`debootstrap`**:

After you enter the **chroot** jail, we need to complete the second stage of the base setup:

   # /debootstrap/debootstrap --second-stage
   

Installing additional packages
——————————-

1. Setup the correct timezone:

   # dpkg-reconfigure tzdata
   

2. Add repositories in ***/etc/apt/sources.list***.

* For Ubuntu:
“`
deb http://ports.ubuntu.com/ trusty main restricted universe multiverse
deb http://ports.ubuntu.com/ trusty-security main restricted universe multiverse
deb http://ports.ubuntu.com/ trusty-updates main restricted universe multiverse
deb http://ports.ubuntu.com/ trusty-backports main restricted universe multiverse

deb-src http://ports.ubuntu.com/ trusty main restricted universe multiverse
deb-src http://ports.ubuntu.com/ trusty-security main restricted universe multiverse
deb-src http://ports.ubuntu.com/ trusty-updates main restricted universe multiverse
deb-src http://ports.ubuntu.com/ trusty-backports main restricted universe multiverse
“`

* For Debian:

“`
deb http://ftp.uk.debian.org/debian jessie main contrib non-free
deb http://ftp.debian.org/debian/ jessie-updates main contrib non-free
deb http://security.debian.org/ jessie/updates main contrib non-free

deb-src http://ftp.uk.debian.org/debian jessie main contrib non-free
deb-src http://ftp.debian.org/debian/ jessie-updates main contrib non-free
deb-src http://security.debian.org/ jessie/updates main contrib non-free
“`

* Run update after adding the repositories:

      # apt-get update
      

2. Install additional software.

* We need to create a fake **`/sbin/initctl`** to prevent **apt** from breaking:

      # dpkg-divert --local --rename --add /sbin/initctl
      # ln -s /bin/true /sbin/initctl
      

* Install the software you need:

      # apt-get -y install language-pack-en ssh isc-dhcp-client net-tools man lsof less
      

* Remove the fake **`/sbin/initctl`**:

      # rm /sbin/initctl
      # dpkg-divert --local --rename --remove /sbin/initctl
      

3. Setup users:

   # passwd root
   # useradd -m -s /bin/bash utilite
   # passwd utilite
   # usermod -a -G adm,cdrom,sudo,dip,plugdev utilite
   

4. Setup a kernel:

Now you need to deploy the [kernel we prepare earlier](/?p=1073#toc-deploy-the-tarball “Building a new Linux kernel for your Utilite Computer”) and reboot.

Choose a role for your system
—————————–

1. After you reboot you may find that networking is not working. If you are in a **dhcp** enabled network run **`dhclient`** to get an IP address:

   # dhclient 
   

2. Upgrade the system to the latest upgrades:

   # apt-get update
   # apt-get -y dist-upgrade
   

3. Check the available roles

* On Ubuntu you may want to install **`tasksel`** (already installed on Debian):

      # apt-get install tasksel
      

* See the available roles on Ubuntu:

      # tasksel --list-tasks
      i server        Basic Ubuntu server
      i openssh-server        OpenSSH server
      u dns-server    DNS server
      u lamp-server   LAMP server
      u mail-server   Mail server
      u postgresql-server     PostgreSQL database
      u print-server  Print server
      u samba-server  Samba file server
      u tomcat-server Tomcat Java server
      u cloud-image   Ubuntu Cloud Image (instance)
      u virt-host     Virtual Machine host
      u ubuntustudio-graphics 2D/3D creation and editing suite
      u ubuntustudio-audio    Audio recording and editing suite
      u edubuntu-desktop-gnome        Edubuntu desktop
      u kubuntu-active        Kubuntu Active
      u kubuntu-desktop       Kubuntu desktop
      u kubuntu-full  Kubuntu full
      u ubuntustudio-font-meta        Large selection of font packages
      u lubuntu-desktop       Lubuntu Desktop
      u lubuntu-core  Lubuntu minimal installation
      u mythbuntu-frontend    Mythbuntu frontend
      u mythbuntu-backend-master      Mythbuntu master backend
      u mythbuntu-backend-slave       Mythbuntu slave backend
      u ubuntustudio-photography      Photograph touchup and editing suite
      u ubuntustudio-publishing       Publishing applications
      u ubuntu-gnome-desktop  Ubuntu GNOME desktop
      u ubuntu-desktop        Ubuntu desktop
      u ubuntu-usb    Ubuntu desktop USB
      u ubuntustudio-video    Video creation and editing suite
      u xubuntu-desktop       Xubuntu desktop
      u edubuntu-dvd-live     Edubuntu live DVD
      u kubuntu-active-live   Kubuntu Active Remix live CD
      u kubuntu-live  Kubuntu live CD
      u kubuntu-dvd-live      Kubuntu live DVD
      u lubuntu-live  Lubuntu live CD
      u ubuntu-gnome-live     Ubuntu GNOME live CD
      u ubuntustudio-dvd-live Ubuntu Studio live DVD
      u ubuntu-live   Ubuntu live CD
      u ubuntu-usb-live       Ubuntu live USB
      u xubuntu-live  Xubuntu live CD
      u manual        Manual package selection
      

* See the available roles on debian:

      $ tasksel --list-tasks
      i desktop	Debian desktop environment
      u gnome-desktop	GNOME
      u xfce-desktop	Xfce
      u kde-desktop	KDE
      u cinnamon-desktop	Cinnamon
      u mate-desktop	MATE
      i lxde-desktop	LXDE
      u web-server	web server
      u print-server	print server
      u ssh-server	SSH server
      u laptop	laptop
      

4. Choose a role.

If you would like a Desktop system, I suggest you choose something light like **lubuntu-desktop** or **lxde-desktop**.

* Installing **Lubuntu** (Ubuntu):

      # tasksel --task-packages lubuntu-desktop | xargs apt-get -y install
      

I prefer this method rather than the [TUI](https://en.wikipedia.org/wiki/Text-based_user_interface “Text-based User Interface”) of **tasksel**, so as to have better overview and control of the process. Keep an eye on it every now and then, because it will ask you about keyboard-configuration and other questions. Select the default settings if you are unsure.

* Installing **LXDE Desktop** (Debian):

      # apt-get install task-lxde-desktop network-manager
      

For Desktop systems it may be a good idea to install **network-manager** as well.

* Add the **vivante** GPU module on startup:

      # echo vivante >> /etc/modules
      

After you finish you can reboot your system and start playing.

References
———-
* https://github.com/umiddelb/armhf/wiki/Installing-Ubuntu-14.04-on-the-utilite-computer-from-scratch
* https://wiki.debian.org/InstallingDebianOn/CompuLab/PC-Utilite/wheezy

Yet another practical packaging session, this ine on how to build a Debian package from scratch. This one too is based on the packaging tutorial and practical sessions of [Lucas Nussbaum](http://www.lucas-nussbaum.net/).

We are going to download the source code of gnujump from upstream, and use the [pbuilder](https://pbuilder.alioth.debian.org/ “Personal Builder”) tool to package it. The advantages of **pbuider** is that it creates a minimal [chroot jail](https://en.wikipedia.org/wiki/Chroot “chroot”) that helps you track any dependencies you might forgot to specify in ***debian/control***. Also it gives you the opportunity to build Debian packages on Ubuntu and vice-versa. You can also build packages for releases other than your own.

Prerequisites
————-

* A recent Debian or Ubuntu system.

Preparation of the **pbuilder** jail
————————————

Install **pbuilder** and relevant packages:

$ sudo apt-get -y install pbuilder debootstrap devscripts packaging-dev debian-keyring ubuntu-archive-keyring

**NOTE: use *ubuntu-keyring* instead of *ubuntu-archive-keyring* if your build station is Ubuntu**

Prepare the target environment. For example for Ubuntu trusty use can use this setup:

$ sudo pbuilder create --debootstrapopts --variant=buildd --mirror http://cy.archive.ubuntu.com/ubuntu --distribution trusty --architecture amd64 --components main --debbuildopts -mJohn Doe \<john.doe@example.net\>

Prepare the new package
————————

1. Download the source:

   $ wget https://ftp.gnu.org/gnu/gnujump/gnujump-1.0.8.tar.gz
   

2. Extract the archive and change into the source tree:

   $ tar xvzf gnujump-1.0.8.tar.gz
   $ cd gnujump-1.0.8/
   

Prepare for debian packaging
—————————-

1. We are going to use the **`dh_make`** utility to prepare the ***debian*** directory and all the necessary files:

   $ DEBFULLNAME="John Doe" DEBEMAIL="john.doe@example.net" dh_make -s -y --createorig
   

Check if all necessary files are there:

   $ find debian/
   debian/
   debian/compat
   debian/manpage.1.ex
   debian/preinst.ex
   debian/rules
   debian/gnujump.default.ex
   debian/README.Debian
   debian/copyright
   debian/gnujump.cron.d.ex
   debian/gnujump.doc-base.EX
   debian/changelog
   debian/README.source
   debian/control
   debian/menu.ex
   debian/manpage.sgml.ex
   debian/docs
   debian/init.d.ex
   debian/source
   debian/source/format
   debian/watch.ex
   debian/postrm.ex
   debian/prerm.ex
   debian/manpage.xml.ex
   debian/postinst.ex
   

Now Check the contents of the ***debian/changelog***, ***debian/rules*** and ***debian/control*** files.

2. We will need to make some changes in the ***debian/control*** file:

   Source: gnujump
   Section: games
   Priority: optional
   Maintainer: John Doe 
   Build-Depends: debhelper (>= 9), autotools-dev, libsdl1.2-dev, libsdl-image1.2-dev, libsdl-mixer1.2-dev
   Standards-Version: 3.9.5
   Homepage: http://gnujump.es.gnu.org
   ...
   

The **libsdl1.2-dev**, **libsdl-image1.2-dev** and **libsdl-mixer1.2-dev** have been discovered by repeatedly compiling and failing until you get it right. The you can use the **`apt-cache search`** and **`apt-file search`** commands to discover the packages corresponding to the missing dependencies.

3. Edit the ***debian/rules*** file to look like this:

“`
DH_VERBOSE = 1

DPKG_EXPORT_BUILDFLAGS = 1
include /usr/share/dpkg/default.mk

export DEB_BUILD_MAINT_OPTIONS = hardening=+all

export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
export DEB_LDFLAGS_MAINT_APPEND = -Wl,–as-needed

%:
dh $@ –with autotools-dev

CFLAGS += -lm
“`

4. Edit the ***debian/changelog***, with **`dch -e`**, to look like this:

“`
gnujump (1.0.8-1) unstable; urgency=low

* Initial release

— John Doe Mon, 22 Jun 2015 17:41:22 +0300
“`

Build the package
—————–

Run this command from the source tree:

$ pdebuild

Give your password when asked. **`pdebuild`** will download and install all dependencies in the **pbuilder** jail and then build the package. Changes will be lost from the jail, the next time you use it but if all goes well, you should see these files under ***/var/cache/pbuilder/result***:

$ ls -la /var/cache/pbuilder/result/
total 5776
drwxr-xr-x 2 root      root         4096 Ιούν 22 17:52 .
drwxr-xr-x 9 root      root         4096 Ιούν 22 11:26 ..
-rw-r--r-- 1 john john    1449 Ιούν 22 17:52 gnujump_1.0.8-1_amd64.changes
-rw-r--r-- 1 john john 1560574 Ιούν 22 17:52 gnujump_1.0.8-1_amd64.deb
-rw-rw-r-- 1 john john    9228 Ιούν 22 17:52 gnujump_1.0.8-1.debian.tar.xz
-rw-rw-r-- 1 john john     885 Ιούν 22 17:52 gnujump_1.0.8-1.dsc
-rw-rw-r-- 1 john john 2508641 Ιούλ 24  2012 gnujump_1.0.8.orig.tar.gz
-rw-rw-r-- 1 john john 1814056 Ιούν 22 17:41 gnujump_1.0.8.orig.tar.xz

Checking the result
——————-

1. View the information related to the package file:

   $ dpkg -I /var/cache/pbuilder/result/gnujump_1.0.8-1_amd64.deb
    new debian package, version 2.0.
    size 1560574 bytes: control archive=5550 bytes.
        419 bytes,    11 lines      control              
      18390 bytes,   233 lines      md5sums              
    Package: gnujump
    Version: 1.0.8-1
    Architecture: amd64
    Maintainer: John Doe 
    Installed-Size: 2355
    Depends: libc6 (>= 2.14), libgl1-mesa-glx | libgl1, libsdl-image1.2 (>= 1.2.10), libsdl-mixer1.2, libsdl1.2debian (>= 1.2.11)
    Section: games
    Priority: optional
    Homepage: http://gnujump.es.gnu.org
    Description: <insert up to 60 chars description>
     <insert long description, indented with spaces>
   

As you can see our work is not finished. We need to add a description in ***debian/control*** and rebuild it.

2. Check the contents of the package file:

   $ dpkg -I /var/cache/pbuilder/result/gnujump_1.0.8-1_amd64.deb
   

Install the package
——————-

Now we can install the package:

$ sudo dpkg -i /var/cache/pbuilder/result/gnujump_1.0.8-1_amd64.deb

Now run the **`gnujump`** software and check if it works.

This is not the whole story of course. You have to check the package against [Lintian](https://lintian.debian.org/ “Lintian Standards Checker”) to see if it complies with the [Debian Policy](https://www.debian.org/doc/debian-policy/ “Debian Policy”). And if it’s not compliant, you may need to use [Quilt](https://wiki.debian.org/UsingQuilt “Quilt Patch Management”) to patch it. You will need to fill ***debian/watch*** so you can track updates on the upstream with **`uscan`**. The work of a Debian packager never ends.

References
———-
* [1] https://wiki.ubuntu.com/PbuilderHowto
* [2] https://www.debian.org/doc/manuals/packaging-tutorial/packaging-tutorial.en.pdf