From 3fb2b9563d9b58a9683808c6620832dc71f76b20 Mon Sep 17 00:00:00 2001 From: Sam Chudnick Date: Thu, 8 Dec 2022 20:44:37 -0500 Subject: Initial commit --- articles/freeipa-server.html | 176 ++++++++++ articles/icinga-agent.html | 135 ++++++++ articles/icinga-director.html | 112 +++++++ articles/icinga-influx.html | 133 ++++++++ articles/icinga-master.html | 276 ++++++++++++++++ articles/luks.html | 132 ++++++++ articles/mail-server.html | 723 ++++++++++++++++++++++++++++++++++++++++++ articles/mdadm-raid.html | 120 +++++++ articles/mutt.html | 27 ++ articles/pam-tfa.html | 157 +++++++++ articles/template.html | 27 ++ 11 files changed, 2018 insertions(+) create mode 100644 articles/freeipa-server.html create mode 100644 articles/icinga-agent.html create mode 100644 articles/icinga-director.html create mode 100644 articles/icinga-influx.html create mode 100644 articles/icinga-master.html create mode 100644 articles/luks.html create mode 100644 articles/mail-server.html create mode 100644 articles/mdadm-raid.html create mode 100644 articles/mutt.html create mode 100644 articles/pam-tfa.html create mode 100644 articles/template.html (limited to 'articles') diff --git a/articles/freeipa-server.html b/articles/freeipa-server.html new file mode 100644 index 0000000..80825d0 --- /dev/null +++ b/articles/freeipa-server.html @@ -0,0 +1,176 @@ + + + + + + + + + + +

FreeIPA Server Setup

+
+

FreeIPA is a centralized idenity management solution developed + by Redhat. It is in my opinion the most functional libre alternative + to Microsoft's Active Directory. Like AD, FreeIPA integrates all of + the pieces needed to setup a domain including LDAP, Kerberos, + a Certificate Authority, and much more.

+ +

I will be using Fedora 35 in this tutorial. As of Debian 11, the + FreeIPA server is still not in the Debian repos. You will need either + a Fedora or a RHEL machine. A CentOS fork may work also but I have not + tested that.

+ +

FreeIPA in an Enterprise

+ +

For readers exploring the use of FreeIPA in a business + environment, note that FreeIPA documentation explicitly states that + it is not a replacement for Active Directory. I have not personally + tried to join a Windows computer to a FreeIPA domain, and so I can't + speak to how well that would work. FreeIPA would also not be able to push + out policy to Windows machines as is done with Group Policy. FreeIPA + is though able to create inter-domain trusts with an existing AD + infrastructure.

+ +

The Case for FreeIPA at Home

+

Using a full Kerberos and LDAP identity management server may + seem like overkill at home. And if you only have a single computer + then it probably is. But scaling up even slightly, to perhaps a small + family each with their own computer, will make having FreeIPA + advantageous (your family is all using Linux, right?). This + will be especially apparent if you are hosting your own services. + If you are for instance hosting a Jellyfin media server that everyone + in your family accesses, you won't want them to juggle separate + passwords for Jellyfin when you could just have them use the same + password they do on the computer. This single/same sign-on capability is + one of the most practically useful aspects of FreeIPA.

+ +

Install Packages

+

We start as usual by installing the required packages.

+ +
dnf install freeipa-server freeipa-dns
+ +

Set Hostname

+

The server will need to have a fully qualified hostname + before setting up IPA. You will need both a hostname for the server + itself and the domain name you will want for the FreeIPA domain. I + will be using ipaserver.myhome.local, where + ipaserver is the hostname and myhome.local is the + domain name.

+ +
hostnamectl set-hostname ipaserver.home.local
+ +

We'll also need to add a hosts file entry to + /etc/hosts. Open that file in an editor and add a new + line with the IP of the server, the fully qualified name, and the + hostname.

+ +
192.168.1.10 ipaserver.myhome.local ipaserver
+ + +

Make sure to reboot the server before continuing to complete + the hostname change.

+ +

Firewall Configuration

+

We'll need to allow several ports for FreeIPA to function properly. + Fedora 35 uses firewalld by default but I am going to disable that + in favor of UFW here.

+ +
#Install UFW
+dnf install ufw
+# Stop and disable firewalld
+systemctl disable --now firewalld
+# Configure UFW
+ufw enable
+ufw allow ssh
+ufw allow dns
+ufw allow 88 comment kerberos
+ufw allow 389 comment ldap
+ufw allow 443 comment webui
+ufw allow 636 comment ldaps
+ufw default deny incoming
+ufw reload
+ +

Configure FreeIPA

+

Now we can run the FreeIPA setup script. This is an interactive but mostly + automatic process that will configure all of the IPA components. The + --mkhomedir flag will configure the server to create home + directories for IPA users on their first login and would otherwise have to be + done manually.

+ +
ipa-server-install --mkhomedir
+ +

That command will bring you into the install script. You will be prompted + several times before the bulk of the configuration happens. Default values + are show in brackets after the prompt. Let's run through those prompts.

+ Do you want to configure integrated DNS (BIND)?: + yes

+ Sever host name: the default value should be showing + ipaserver.myhome.local which is what we want. Simply hit enter to acecpt + the default.

+ Please confirm the domain name: The default here should be + correct myhome.local so hit enter to accept that.

+ Please provide a realm name: This should just be the domain + name in all uppercase. If the default looks correct just hit enter.

+ Directory Manager password: This is the password for an + administrator account used by system services. You will not need this for daily + use so I recommend setting it to a long randomly generated string. I have found + myself that using an extremely long password here will cause the installation to + fail. A password under 40 characters should be safe.

+ IPA admin password: This is the password for your initial admin + user. Make this a strong password as this user has full admin rights for the + entire domain.

+ Do you want to configure DNS forwarders: This allows you to + configure the IPA server to forward DNS requests to another DNS server for + zones it is not authoratitve for. The DNS server is configured by default as + a recursive DNS server so answering no does not prevent internet access. If you + have another DNS server that should be used instead then answer yes and provide + the IP address when prompted.

+ + Do you want to configure chrony with NTP server or pool address? + : Here you can configure a custom NTP server or pool for the NTP daemon chrony. + If you already have an NTP server on your network answer yes and provide its IP. + If you want to leave the deafult chrony configuration then answer no. Time + synchronization is very important in Kerberos so you should consider how you + want to achieve that on your network. If you do not have an NTP server you may + want to configure the IPA server as one later.

+ + Continue to configure the system with these values?: This is a + final confirmation before the script takes over and configures the IPA + components. Review the information printed and enter yes if it all looks correct. +

+ +

The install script will now run through configuration. This process usually + takes several minutes. When finished you should get a message saying + The ipa-server-install command was successful.

+ +

To finish, run this command to receive a Kerberos TGT. Provide the + password for the admin user when prompted.

+ +
kinit admin
+ +

Accessing the Web Interface

+ +

You are now able to manage FreeIPA through the web interface. You can + browse either to the IP or the hostname if your DNS is configured correctly. + You should see a screen similar to this.

+ + FreeIPA Login Screen + +

Login with the username admin and the password you set during the + insallation. You are now ready to begin configuring your IPA domain.

+
+

+


+Consider donating if this article was useful. +[BTC] +

+ + + + + diff --git a/articles/icinga-agent.html b/articles/icinga-agent.html new file mode 100644 index 0000000..e0aa6c0 --- /dev/null +++ b/articles/icinga-agent.html @@ -0,0 +1,135 @@ + + + + + + + + + + +

Icinga Agent Node Installation and Configuration

+
+

With the Icinga master node configured, the servers we want + to monitor can now be added as agent nodes. As the names suggest, + the Icinga master node pushes the desired configuration to agent + nodes, while agent nodes report the configured status checks back + to the master. Communication between the master and agent nodes is + encrypted via TLS, with the master node acting as a certificate + authority.

+ +

You can find my script to automate this process + + here.

+ +

Install Pakcages

+

Start by installing the required packages on the server to be + monitored.

+ +
apt install icinga2 monitoring-plugins 
+monitoring-plugins-contrib
+ +

Initialize PKI with master

+

Now we need to setup the PKI that will be used for the communication + with the master node. The first step is to generate a certificate + signing request. Replace hostname with the FQDN of the server.

+ +
icinga2 pki new-cert --cn "hostname" --cert "/etc/icinga2/pki/hostname.crt" --csr "/etc/icinga2/pki/hostname.csr" --key "/etc/icinga2/pki/hostname.key"
+ +

Next we save the master node's public key certificate. Replace + master with the FQDN of your master node.

+ +
icinga2 pki save-cert --host "master" --port 5665 --key "/etc/icinga2/pki/hostname.key" --trustedcert "/etc/icinga2/pki/trusted-master.crt"
+ +

Receive signed certificate from the master node.

+ +
icinga2 pki request --host "master" --port 5665 --key "/etc/icinga2/pki/hostname.key" --cert "/etc/icinga2/pki/hostname.crt" --trustedcert "/etc/icinga2/pki/trusted-master.crt" --ca "/etc/icinga2/pki/ca.crt"
+ +

Deploy configuration files

+

Write Icinga configuration.

+ +
/etc/icinga2/icinga2.conf 
+include "constants.conf"
+const NodeName = "$nodename"
+include "zones.conf"
+include "features-enabled/*.conf"
+include <itl>
+include <plugins>
+include <plugins-contrib>
+include <manubulon>
+include <windows-plugins>
+include <nscp>"
+ +

Write zones configuration.

+ +
/etc/icinga2/zones.conf 
+echo "object Endpoint "hostname" {}
+object Zone "hostname" {
+  parent = "master"
+  endpoints = [ "hostname" ]
+}
+object Zone "master" {
+  endpoints = [ "master" ]
+}
+object Endpoint "master" {
+  host = "master"
+}
+object Zone "director-global" {
+  global = true
+}
+ +

Write API configuration file.

+ +
/etc/icinga2/features-available/api.conf 
+echo "object ApiListener \"api\" {
+  accept_commands = true
+  accept_config = true
+}
+ +

Enable API

+

Next, we need to enable the API on the agent.

+ +
icinga2 feature enable api
+
+mkdir -p /var/lib/icinga2/certs
+
+cp /etc/icinga2/pki/hostname.crt /etc/icinga2/pki/hostname.key /etc/icinga2/pki/ca.crt /var/lib/icinga2/certs/
+
+chown -R nagios: /var/lib/icinga2/certs/
+ +

Sign agent CSR on Master

+

The only action needed on the master node is to sign the agent's + CSR. Logon to your master node and run the following:

+ +
fpr="$(icinga2 ca list | tail -1 | cut -d '|' -f 1)"
+icinga2 ca sign $fpr
+ +

Configure Firewall

+

Before finishing we need to open the proper firewall port. + I will use UFW in the example here and allow traffic only only + from the master node for best security.

+ +
ufw allow proto tcp from master-ip to any port 5665
+ +

Restart Icinga on Agent

+

Finally, restart the icinga service on the agent node.

+ +
systemctl restart icinga2
+ +

The Icinga agent node will now pull down configuration from the master. + You will know that this worked if /var/lib/icinga2/api/zones + begins to populate with new files.

+

+


+Consider donating if this article was useful. +[BTC] +

+
+ + + + diff --git a/articles/icinga-director.html b/articles/icinga-director.html new file mode 100644 index 0000000..3993949 --- /dev/null +++ b/articles/icinga-director.html @@ -0,0 +1,112 @@ + + + + + + + + + + +

Icinga Director

+
+

Icinga Director is the web-based configuration tool for Icinga2. + Director provides a simple interface for configuring the various parts + of your monitoring environment. Even if you would rather do all of + the configuration from a terminal, I still recommend using Director for + its self-service API which allows new nodes to register with no interaction + required on the node (i.e. via a script).

+ +

Start by logging into your Icinga instance. If you followed the + master installation guide you should have + a tab labeled Icinga Director. Click on that, and you should + see something similar to this:

+ + +

Hosts

+

Let's start by looking at the hosts section. Clicking on the hosts + button from the Director menu will present you with several options. + Click on host templates, and then click add to define our first host + template. Host templates are the building blocks of Icinga, they allow + for your nodes to be structured however you see fit, and then to have + monitoring checks automatically applied to them based on that structure.

+

I like to structure my host templates by operating system. For example, + I have a template called Linux Server, which is designed + to encompass all of the Linux servers in my environment. I then get more + specific, creating templates based on distro. These templates are children + of the Linux Server template, so they inherit whatever is applied to the + parent, but then can have distro-specific checks applied to themselves.

+

Start by giving your template a name - I will use Linux Server + here. Groups can be left empty for now, but you may want to + add groups and apply them to templates later. The check command should + be set to hostalive. Expand Icinga Agent and zone settings + and set Icinga2 Agent, Establish connection, + and Accepts config to Yes. Click store to save the template. + Your template should look like this:

+ + + +

Service templates

+

Let's turn to services now. Return to the Director menu and select + Services. The services menu is structured similar to hosts, and we will + start with the service templates section. The idea behind service templates + is very similar to host templates. Typically, a service template corresponds + to a single monitoring command.

+

As an example, we'll create a service template for a monitoring + command that checks the status of a web server. Give the template a + name, set the check command to http, and finally expand Icinga + Agent and zone settings and set Run on agent + to no. We set this to no because we want Icinga to query + the web server externally instead of from the web server itself.

+ + + +

Service sets

+

Service sets are simply groups of service templates. They can be + structured however you see fit. Service sets can then be applied to + hosts/host templates to have the checks be automatically applied.

+ +

Add a new service set and give it a name. Then click on the services + tab and add all of the services you want to group into that set. + Here is an example of a service set Linux Standard + that has service checks that should be applied to all Linux servers.

+ + + +

To bring service sets and host templates together, return to your host + templates, select Linux Server, select the services tab, and then select + add service set and choose your desired set from the dropdown menu.

+ + + +

Render your config

+

When you have made all of the changes you need you will need to + render the Director configuration. Return to the Director menu, + select Config Deployment, and then select Render config.

+ +

Self Service API

+

In this last section we will look at what I think is the best feature + of Director which is the self service API. To enroll a host template + in the self service API, select the host template, select the agent + tab, and select generate self service api key. That's it! + The string of letters and numbers is the API key associated with this + host template. Hosts can be enrolled with this API key and Icinga + will automatically assign the host to this template. With proper + structuring, you can have hosts be completely provisioned without + touching Director. In the next article, we will use this to enroll + a host in Icinga with a shell script.

+

+


+Consider donating if this article was useful. +[BTC] +

+
+ + + + + diff --git a/articles/icinga-influx.html b/articles/icinga-influx.html new file mode 100644 index 0000000..8d96c88 --- /dev/null +++ b/articles/icinga-influx.html @@ -0,0 +1,133 @@ + + + + + + + + + + +

Integrating InfluxDB and Icinga

+
+

Icinga2 has built-in support for writing monitoring data to InfluxDB. + This makes Icinga quite extensible as it allows for other programs to read + the gathered data from InfluxDB. For example, Icinga does not have built-in + graphing support. But monitoring data can be written to InfluxDB and then + consumed by a dedicated graphing tool like Grafana.

+ +

Install Packages

+

Let's install a few necessary packages

+ +
apt install influxdb influxdb-client ssl-cert
+ +

Generate self-signed certificate

+

Now generate a self-signed certificate for accessing InfluxDB over TLS

+ +
make-ssl-cert generate-default-snakeoil
+usermod -aG ssl-cert influxdb
+ +

Create Database and Users

+

Start and enable the InfluxDB service

+ +
systemctl enable --now influxdb
+ +

Now we'll create our database and users. We'll be creating 3 users with + different access rights. An admin user with full control over the database, a + user with write access that Icinga will use to write data to the database, and + a read-only user to allow external programs to read data from the database.

+ +
influx -ssl -unsafeSsl -execute "create database icinga2; create user admin with password 'changeme'; create user icingauser with password 'changeme'; create user readonly with password 'changeme'; grant all to admin; grant write on icinga2 to icingauser; grant read on icinga2 to readonly;"
+
+ +

Configuration Files

+ +

Then write InfluxDB's configuration file at + /etc/influxdb/influxdb.conf

+ +
reporting-enabled = false
+[meta]
+  dir = "/var/lib/influxdb/meta"
+[data]
+  dir = "/var/lib/influxdb/data"
+  wal-dir = "/var/lib/influxdb/wal"
+[coordinator]
+[retention]
+[shard-precreation]
+[monitor]
+[http]
+  enabled = true
+  bind-address = ":8086"
+  auth-enabled = true
+  https-enabled = true
+  https-certificate = "/etc/ssl/certs/ssl-cert-snakeoil.pem"
+  https-private-key = "/etc/ssl/private/ssl-cert-snakeoil.key"
+[ifql]
+[logging]
+[subscriber]
+[[graphite]]
+[[collectd]]
+[[opentsdb]]
+[[udp]]
+[continuous_queries]
+[tls]
+  min-version = "tls1.2"
+ +

And restart InfluxDB to pickup the changes

+ +
systemctl restart influxdb
+ +

Then we need to configure Icinga to write data to our database. Start by + enabling the influxdb feature in Icinga

+ +
icinga2 feature enable influxdb
+ +

Now we tell Icinga how to write to our database. Open the configuration + file at /etc/icinga2/features-available/influxdb.conf and replace + with the following

+ +
object InfluxdbWriter \"influxdb\" {
+  host = "127.0.0.1"
+  port = 8086
+  username = "icingauser"
+  password = "icinga_password"
+  ssl_enable = true
+  database = "icinga2"
+  flush_threshold = 1024
+  flush_interval = 10s
+  host_template = {
+  measurement = "$host.check_command$"
+    tags = {
+      hostname = "$host.name$"
+    }
+  }
+  service_template = {
+    measurement = "$service.check_command$"
+    tags = {
+      hostname = "$host.name$"
+      service = "$service.name$"
+    }
+  }
+}
+ +

And finally restart Icinga to make those changes live.

+ +
systemctl restart icinga2
+ +

Icinga2 will now be writing the data it collects to your InfluxDB instance.

+ +
+

+


+Consider donating if this article was useful. +[BTC] +

+ + + + + diff --git a/articles/icinga-master.html b/articles/icinga-master.html new file mode 100644 index 0000000..0cafcdd --- /dev/null +++ b/articles/icinga-master.html @@ -0,0 +1,276 @@ + + + + + + + + + + +

Icinga2 Master Installation

+
+

+This tutorial will cover the installation of the Icinga2 +monitoring application master node. This includes the base +program, the web frontend, and the web-based configuration tool. +This guide was made for Debian but should be similar +on other distributions. +

+

+I have a script available to automate the steps described in this +tutorial available +from my git repo. +

Install Packages

+

Here we will install the required packages. Icinga can use either MySQL +or PostgreSQL, however this tutorial will use MySQL/MariaDB.

+
apt install icinga2 icingaweb2 icinga2-ido-mysql icingaweb2-module-director monitoring-plugins monitoring-plugins-contrib default-mysql-server
+

Secure MySQL

+

This step is optional but strongly recommended. +The mysql_secure_installation script will harden your MySQL instance.

+
mysql_secure_installation
+

I recommend the following responses: +

+

+ +

Create Monitoring Database

+

The next several sections will cover creating databases for the various +parts of Icinga. We'll start with the monitoring database. +The following command creates a MySQL database named icinga2 +and grants permissions to a user named ido_admin. These values +are arbitrary, but I use them throughout the tutorial so I recommend leaving them +as is. You should definitely change the password though, which in the command +is change me. You will need this password and the passwords for the +other databases later, so make sure you save them.

+
mysql -u root -e "CREATE DATABASE icinga2; GRANT SELECT, INSERT, UPDATE, DELETE, DROP, CREATE VIEW, INDEX, EXECUTE ON icinga2.* TO ido_admin@'localhost' IDENTIFIED BY 'change me'; FLUSH PRIVILEGES;
+ +

We then need to import the ido schema into the database.

+ +
mysql -u root icinga2 </usr/share/icinga2-ido-mysql/schema/mysql.sql
+ +

After importing the schema, we then write the configuration file that tells +the monitoring module how to connect to the database.

+
/etc/icinga2/features-available/ido-mysql.conf
+library "db_ido_mysql"
+object IdoMysqlConnection "ido-mysql" {
+	user = "ido_admin",
+	password = "ido_password",
+	host = "localhost",
+	database = "icinga2"
+}"
+ +

And finally we enable the monitoring module in Icinga.

+
icinga2 feature enable ido-mysql
+ +

Create Icingaweb2 Database

+

This step is nearly identical to the last. This time we create a database +named icingaweb2 and grant permissions to the user named +icingaweb2_admin.

+
mysql -u root -e "CREATE DATABASE icingaweb2;GRANT ALL ON icingaweb2.* TO 'icingaweb2_admin'@'localhost' IDENTIFIED BY 'changeme'; FLUSH PRIVILEGES;
+ +

Again we will need to import required schema into the database.

+
mysql -u root icingaweb2 </usr/share/icingawbe2/etc/schema/mysql.schema.sql
+ + +

In this step we create the initial admin user that will be used to login +to the web interface. As is, this would create a user named admin +with the password changme. You should at least change the password.

+
passhash="$(php -r "echo password_hash(\"changeme\", PASSWORD_DEFAULT);")"
+mysql -u root -e "USE icingaweb2; INSERT INTO icingaweb_user (name, active, password_hash) VALUES (\"admin\", 1, \"$passhash\"); FLUSH PRIVILEGES;"
+ +

Create Icinga Director Database

+

Here we create the database for Director. Director will require more +configuration later, so for now we will just be creating the database.

+
mysql -u root -e "CREATE DATABASE director CHARACTER SET 'utf8'; GRANT ALL on director.* TO 'director'@'localhost' IDENTIFIED BY '$director_password';FLUSH PRIVILEGES;"
+ +

Setup Icinga2 API

+

Run the following command to initialize the Icinga API.

+
icinga2 api setup
+

And then restart Icinga to apply the changes.

+
systemctl restart icinga2
+ +

Configure Web Server

+

In this section we will configure the web server for accessing +Icinga's web interface and Director configuration tool. +This tutorial will use nginx but apache could be used as well. +We'll start by installing the necessary packages.

+
apt install nginx php-fpm
+

Then we need to create the site configuration file.

+

/etc/nginx/sites-available/icingaweb2.conf
+server {
+  listen 80;
+  server_name monitoring.example.com
+  location ~ ^/icingaweb2/index\.php(.*)$ {
+    fastcgi_pass unix:/var/run/php/php-fpm.sock;
+    fastcgi_index index.php;
+    include fastcgi_params;
+    fastcgi_param SCRIPT_FILENAME /usr/share/icingaweb2/public/index.php;
+    fastcgi_param ICINGAWEB_CONFIGDIR /etc/icingaweb2;
+    fastcgi_param REMOTE_USER $remote_user;
+  }
+
+  location ~ ^/icingaweb2(.+)? {
+    alias /usr/share/icingaweb2/public;
+    index index.php;
+    try_files $1 $uri $uri/ /icingaweb2/index.php$is_args$args;
+  }
+
+  # Not strictly necessary but allows you to get to icinga without 
+  # specifying /icingaweb2 in the URL.
+  location = / {
+    return 302 http://$host/icingaweb2;
+  }
+
+}
+

And then restart nginx to pick up the changes.

+
systemctl restart nginx
+ +

At this point we are done with the Icinga setup module and so we +can disable it.

+
icingacli module disable setup
+ +

Write Configuration Files

+

In this section we will write several configuration files. Icinga uses +the INI format for its web interface configuration files.

+

In this first file we tell Icinga about the various resources it should have +access to. These resources are the three databases created previously. +Replace the password in each section with the corresponding password you set +for that database earlier.

+
/etc/icingaweb2/resources.ini
+[icinga2]
+type = "db"
+db = "mysql"
+host = "localhost"
+port = ""
+dbname = "icinga2"
+username = "ido_admin"
+password = "ido password"
+charset = ""
+use_ssl = "0"
+
+[icingaweb2]
+type = "db"
+db = "mysql"
+host = "localhost"
+port = ""
+dbname = "icingaweb2"
+username = "icingaweb2_admin"
+password = "ido password"
+charset = ""
+use_ssl = "0"
+
+
+[director]
+type = "db"
+db = "mysql"
+host = "localhost"
+port = ""
+dbname = "director"
+username = "director"
+password = "director password"
+charset = "utf8"
+use_ssl = "0"
+
+ +

This file controls the authentication settings for the web interface. +Here we tell Icinga to look at the icingaweb2 database for +authentication purposes.

+
/etc/icingaweb2/authentication.ini
+[icingaweb2]
+backend = "db"
+resource = "icingaweb2"
+ +

Now we tell icinga which users should have admin permissions. +If you changed the username value from admin previously, be sure to update +it here.

+
/etc/icingaweb2/roles.ini
+[admins]
+users = "admin"
+resource = "icingaweb2"
+ +

Enable the web interface monitoring module.

+
icingacli module enable monitoring
+

Then write the configuration file pointing the monitoring module to the +monitoring database.

+
/etc/icingaweb2/modules/monitoring/backends.ini
+[icinga]
+type = "ido"
+resource = "icinga2"
+ +

Here we configure Icinga to use the API for communication. +You will need to get your unique API password generated during the API setup from +from /etc/icinga2/conf.d/api-users.conf. +hostname should be the FQDN of the server.

+
/etc/icingaweb2/modules/monitoring/commandtransports.ini
+[icinga2]
+transport = "api"
+host = hostname
+port = "5665"
+username = "root"
+password = "api password"
+ +

Lastly, tell Icinga to protect variables with potentially sensitive values.

+
/etc/icingaweb2/modules/monitoring/config.ini
+[security]
+protected_customvars = "*pw*,*pass*,*community*"
+ + +

Configure Director

+

This section will cover configuring Director configuration tool.

+

Create Director module configuration directory.

+
mkdir -p /etc/icingaweb2/modules/director
+ +

Write the Director configuration file.

+
/etc/icingaweb2/modules/director/config.ini
+[db]
+resource = "director"
+ +

Enable Director module and run the initial migration.

+
icingacli module enable director
+icingacli director migration run
+ +

Write Director kickstart configuration file.

+
/etc/icingaweb2/modules/director/kickstart.ini
+[config]
+endpoint = "hostname"
+username = "root"
+password = "api password"
+ +

Kickstart Director, then render and deploy the configuration.

+
icingacli director kickstart run
+icingacli director config render
+icingacli director config deploy
+ +

Director is setup at this point so we will shred the unneeded configuration +file containing sensitive information.

+
shred -uz /etc/icingaweb2/modules/director/kickstart.ini
+ +

Login to your Monitoring Instance

+

You are now ready to login to your monitoring instance with the admin +user created previously. Open a web browser and go to +http://hostname/icingaweb2. You should see a screen similar to this:

+Icinagweb2 Login Screen + +

Next Steps

+

In the following articles we will go through setting up Icinga2 agents on servers, and configure your monitoring instance through Icinga Director.

+

+


+Consider donating if this article was useful. +[BTC] +

+
+ + + + diff --git a/articles/luks.html b/articles/luks.html new file mode 100644 index 0000000..d2bbc5e --- /dev/null +++ b/articles/luks.html @@ -0,0 +1,132 @@ + + + + + + + + + + +

LUKS Block Device Encryption

+
+

Linux Unified Key Setup (LUKS) is a method for encrypting + block devices that is built-in to the Linux Kernel. In this tutorial + I will be showing how to create an encrypted USB drive with LUKS, but + this process is applicable to other types of storage. + This process will wipe all data on the device that you + encrypt so make backups beforehand if needed.

+ +

Install Packages

+

Install cryptsetup and its dependencies

+ +
apt install cryptsetup
+ +

Prepare the Drive

+

If the device you are encrypting was previously used, you will + want to completely overwrite any data on it before encryption. This + can be done using dd as shown below. This could take + a very long time depending on the size and type of your drive. + Be sure that you enter the correct path to your drive as the + argument to of, and do not specify a partition: + /dev/sdb is correct, /dev/sdb1 is + wrong. Obviously this will destroy any data on the device so be + absolutely sure you specify the correct device in the command + and have backups of data previously stored if needed.

+ +
dd if=/dev/zero of=/dev/sdX status=progress
+ +

Encrypt the Drive

+

cryptsetup is the main command used to perform + LUKS-related tasks. This main command is followed by a subcommand + that specifies which action to perform. To create a LUKS partition + on a drive we need to use the subcommand luksFormat. + We also use the type option to explicitly say to use LUKS version 2 + encryption. Run the command and then enter and confirm the + encryption password.

+ +
cryptsetup --type luks2 luksFormat /dev/sdX
+ +

Now we need to open and map the encrypted LUKS device. This is done + by using the luksOpen subcommand. This subcommand takes + the device as the first argument and then a map target as the second. The + map target can be any string as long as a map does not already exist with + that name. In the example I will use crypt. + +

cryptsetup luksOpen /dev/sdX crypt
+ +

And then we just need to create a filesystem on the device; I will + be making an ext4 filesystem in the example. To + interact with an encrypted drive after it has been opened you need + to refer to its device mapper target, which is found under /dev/mapper. + Since we used crypt as the map target, our encrypted drive + is /dev/mapper/crypt.

+ +
mkfs.ext4 /dev/mapper/crypt
+ +

After creating the filesystem created the encrypted drive + can now be mounted and used like any other device. Remember that + when mounting the device you refer to the device mapper target + (mount /dev/mapper/crypt /mnt/crypt).

+ +

In addition to unmounting the filesystem you should always close + the device mapping before removing your encrypted drive. This is + done with the luksClose subcommand and takes + the device mapping as the argument.

+ +
cryptsetup luksClose /dev/mapper/crypt
+ +

The LUKS Header

+

The LUKS header sits at the front of your encrypted drive and is + responsible for managing access to the device. If the header is + damaged accessing your encrypted data will not be possible. Because of + this, you may want to make backups of the header, but before doing so + you need to weigh the risks and benefits.

+ +

The obvious benefit is that + in the event of damage to the LUKS header, you can easily restore a + backup and regain access to the data. However, having a backup of the + header makes it harder to wipe the LUKS device. Without a header + backup, overwriting the LUKS header on the device is enough to securely + wipe the drive. With backups, you need to either destroy all header + backups or overwrite all encrypted data on the device. The other main risk + is that an encryption password that is valid at the time you make a + backup will always be valid for that backup. For example, say you change + the encryption password on your device after making a backup because it + has been compromised. An attacker would be able to restore the header + backup and then use the compromised password to access the data.

+ +

The cryptsetup documentation refers to creating header backups + as making a trade-off between safety and security. You need to make a + decision based on your individual use-case. It's a good idea to + routinely update your header backups if you do choose to make them

+ +

When creating or restoring a header backup you always refer to the + block device in the command, not the device mapper taget. To create + a header backup:

+ +
cryptsetup luksHeaderBackup /dev/sdX --header-backup-file path/to/backup
+ +

To restore a header from a backup:

+ +
cryptsetup luksHeaderRestore /dev/sdX --header-backup-file path/to/backup
+ +

Note that is not necessary to store header backups on an encrypted + device. I would recommend storing backups on at least one non-encrypted + drive in case of an emergency.

+ +
+

+


+Consider donating if this article was useful. +[BTC] +

+ + + + + diff --git a/articles/mail-server.html b/articles/mail-server.html new file mode 100644 index 0000000..12a3264 --- /dev/null +++ b/articles/mail-server.html @@ -0,0 +1,723 @@ + + + + + + + + + + +

Postfix and Dovecot Mail Server

+
+ +

Postfix and dovecot will be the two primary pieces of our mail sever. +Postfix is the mail transport agent that handles the sending and +receiving of mail and dovecot is the IMAP server that will allow us to +access our mail from a mail client such as mutt. The server will also +have several other supporting components, a complete list of which is:

+ + + +

You can use +this script I have written to automate this process, but I would +recommend that you run through the tutorial first to understand +what is being done.

+ +

Please note that this tutorial is loosely intended for small personal mail +servers. Using PAM for authentication, as is done here, is not a scalable solution +for working with a large number of users. I do plan on covering Dovecot LDAP +authentication at some point which would be a better solution in an enterprise +setting.

+ +

Install Packages

+

Let's start by installing the required packages. Note that if you already +have Apache installed on the server, replace python3-certbot-nginx +with python3-certbot-apache.

+
apt install postfix dovecot-imapd dovecot-sieve opendkim opendkim-tools spamassassin gnupg postgrey postfix-policyd-spf-python opendmarc dbconfig-no-thanks certbot python3-certbot-nginx
+

During the installation of Postfix you will get a Debconf prompt in which +you need to select "Internet Site" and then provide your domain name, +example.com.

+ +

Get a certificate

+

Now we'll use Certbot to get a certificate for our server. If you are +using Apache replace nginx with apache2.

+ +
systemctl stop nginx
+certbot certonly --standalone -d mail.example.com 
+systemctl start nginx
+ +

Postfix Main Configuration

+

In this section we will be doing the bulk of the postfix configuration. +The postconf command used throughout appends (or changes) +the specified configuration item in /etc/postfix/main.cf

+ +

Network Configuration

+ +

Let's start by configuring some network and domain information.

+ +
postconf -e "myorigin = example.com"
+postconf -e "mydestination = \$myhostname, \$mydomain, localhost"
+postconf -e "mynetworks = 127.0.0.0/8 [::1]/128"
+postconf -e "myhostname = mail.example.com"
+
+ +

Next, point postfix to the cerbot key and certificate, as well as the distro's +CA certificates.

+ +
postconf -e "smtpd_tls_key_file=/etc/letsencrypt/live/mail.example.com/privkey.pem"
+postconf -e "smtpd_tls_cert_file=/etc/letsencrypt/live/mail.example.com/fullchain.pem"
+postconf -e "smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt"
+
+ +

Harden the TLS configuration by forcing strong +protocols and ciphers, and requiring that authentication occur only over an +encrypted session.

+
# Require authentication over TLS and optionally use it for sending and receiving mail
+postconf -e "smtpd_tls_auth_only = yes"
+postconf -e "smtpd_tls_security_level = may"
+postconf -e "smtp_tls_security_level = may"
+
+# Force the use of TLSv1.2 or TLSv1.3
+postconf -e 'smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1'
+postconf -e 'smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1'
+postconf -e 'smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1'
+postconf -e 'smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1'
+
+# Prefer server ciphers
+postconf -e "tls_preempt_cipherlist = yes"
+
+# Force strong ciphers
+postconf -e "smtpd_tls_ciphers = high"
+postconf -e "smtpd_tls_mandatory_ciphers = high"
+postconf -e "smtp_tls_ciphers = high"
+postconf -e "smtp_tls_mandatory_ciphers = high"
+postconf -e "smtpd_tls_exclude_ciphers = aNULL, eNULL, EXP, LOW, MEDIUM, PSK, SRP, SHA1, kRSA, CAMELLIA, ARIA, DSS, RSA+AES, ADH, AECDH"
+postconf -e "smtp_tls_exclude_ciphers = aNULL, eNULL, EXP, LOW, MEDIUM, PSK, SRP, SHA1, kRSA, CAMELLIA, ARIA, DSS, RSA+AES, ADH, AECDH"
+
+ +

Local Recipients and Aliases

+ +

Here we configure the bulk of the postfix built-in security settings which are +structured as a series of access restrictions. Do not edit these settings without +first reading the Postfix documentation as an incorrect change could inadvertently +make your server an open relay.

+ +
postconf -e "smtpd_helo_required = yes"
+postconf -e "smtpd_sender_login_maps = proxy:hash:/etc/postfix/login_maps"
+postconf -e "smtpd_helo_restrictions = reject_unknown_helo_hostname, reject_non_fqdn_helo_hostname" 
+postconf -e "smtpd_sender_restrictions = reject_sender_login_mismatch, reject_non_fqdn_sender, reject_unknown_sender_domain"
+postconf -e "smtpd_recipient_restrictions = reject_non_fqdn_recipient, reject_unknown_recipient_domain, permit_sasl_authenticated, reject_unauth_destination, check_policy_service unix:private/postgrey, check_policy_service unix:private/policyd-spf, reject_rbl_client zen.spamhaus.org"
+postconf -e "smtpd_relay_restrictions = permit_sasl_authenticated, reject_unauth_destination"
+postconf -e "smtpd_data_restrictions = reject_unauth_pipelining"
+
+# Disable VRFY command to prevent harvesting of user accounts on system
+postconf -e "disable_vrfy_command = yes"
+
+# Change smptd banner (hide distribution)
+postconf -e "smtpd_banner = \$myhostname ESMTP \$mail_name"
+ +

Now, configure the local mail recipients and some aliases. We'll create +an account called mailadmin to receive mail addressed to +several other accounts. This is to keep administrative mail separate, but +you can certainly alias these to your main account later if you would prefer to see +it there.

+ +
# Set a custom local_recipient_maps here in order to avoid accepting mail for all local accounts
+postconf -e "local_recipient_maps = proxy:hash:/etc/postfix/local_maps \$alias_maps"
+
+# You will need to manually set a password later to login as mailadmin
+adduser --disabled-login --shell /usr/sbin/nologin --gecos "" mailadmin
+echo "# postfix aliases
+postmaster:     mailadmin
+root:           mailadmin
+dmarc:          mailadmin
+" > /etc/aliases
+
+# Update address databases
+echo "mailadmin@mail.example.com    mailadmin" > /etc/postfix/login_maps
+echo "mailadmin mailadmin" > /etc/postfix/local_maps
+newaliases
+postmap /etc/postfix/login_maps
+postmap /etc/postfix/local_maps
+
+ +

Mail Delivery

+ + +

These commands configure our mail delivery preferences. Mail will be +delivered inside a user's home folder with a maildir-style mailbox using +dovecot.

+ +
# Maildir delivery to $HOME/Mail/Inbox/
+postconf -e "home_mailbox = Mail/Inbox/"
+# Deliver mail with Dovecot
+postconf -e "mailbox_command = /usr/lib/dovecot/deliver"
+ +

Header and Body Checks

+ +

Header and body checks allow for some simple content filtering within Postfix. +This is done by scanning a message line by line for a configured regex string, +nothing more. For example, the first header check listed will reject a message +with an attachment of ransomware.exe but will not block it if sent with +no extension. This is mostly a protection against uneducated users and poorly +written mail clients. Other checks block vulnerabilities and improve privacy.

+ +

Create a new file /etc/postfix/header_checks, then open it in a +text editor and add the following

+
# Block files with common executable extensions
+/name=[^>]*\.(exe|pif|com|dll|vbs|bat|sh|bash|so|zip|tar|gz|cpio)/ REJECT
+
+# Block message/partial vulnerability
+/message\/partial/ REJECT
+
+# Remove Received string that is created when spamassassin reinjects message into postfix
+# This is to prevent leaking the userid of the spamassassin user
+/^Received:.*userid.*/  IGNORE
+
+# Remove User-Agent strings from headers
+/^User-Agent: .*/       IGNORE
+ +

Create another new file /etc/postfix/body_checks, and add this

+
# Block messages with iframes
+/<iframe/ REJECT" > /etc/postfix/body_checks
+ +

And then run these commands to point postfix to the check files.

+
postconf -e "header_checks = regexp:/etc/postfix/header_checks"
+postconf -e "body_checks = regexp:/etc/postfix/body_checks"
+ +

Postfix Master Configuration

+

SMTP client

+

This simple command configures the SMTP client process that is responsible +for sending your mail to other mail servers.

+ +
postconf -M "smtp/unix=smtp unix - - y - - smtp"
+ +

Postscreen and SMTP Recipient

+

Postscreen is a kind of firewall that sits in front of the Postfix SMTPD +process and receives all incoming traffic. Postscreen will drop connections +from IPs on a DNS blacklst, or from clients that violate the SMTP protocol by +speaking out of turn or sending non-SMTP commands. This adds up to less spam +connections and therefore a much lighter workload for your server.

+ +
postconf -M "smtp/inet=smtp inet n - y - 1 postscreen"
+postconf -M "smtpd/pass=smtpd pass - - y - - smtpd"
+postconf -P "smtpd/pass/content_filter=spamassassin"
+postconf -M "tlsproxy/unix=tlsproxy unix - - y - 0 tlsproxy"
+postconf -M "dnsblog/unix=dnsblog unix - - y - 0 dnsblog"
+postconf -e "postscreen_dnsbl_sites = zen.spamhaus.org"
+postconf -e "postscreen_dnsbl_action = enforce"
+postconf -e "postscreen_greet_action = enforce"
+
+ +

Submission over TLS (submissions)

+

Submission over TLS (aka submissions) is the process you will use to submit +mail to your server from a mail client. These commands configure submissions to +use a fully-encrypted session, as opposed to STARTTLS, and to only allow access +to authenticated clients.

+ +
postconf -M "submissions/inet=submissions inet n - y - - smtpd"
+postconf -P "submissions/inet/smtpd_tls_wrappermode=yes"
+postconf -P "submissions/inet/smtpd_tls_security_level=encrypt"
+postconf -P "submissions/inet/smtpd_tls_auth_only=yes"
+postconf -P "submissions/inet/smtpd_sasl_auth_enable=yes"
+postconf -P "submissions/inet/smtpd_client_restrictions=permit_sasl_authenticated,reject"
+postconf -P "submissions/inet/smtpd_helo_restrictions="
+postconf -P "submissions/inet/smtpd_sender_restrictions=reject_sender_login_mismatch"
+postconf -P "submissions/inet/smtpd_recipient_restrictions=reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_sasl_authenticated,reject"
+postconf -P "submissions/inet/syslog_name=postfix/submissions"
+postconf -P 'submissions/inet/smtpd_tls_protocols=!SSLv2,!SSLv3,!TLSv1,!TLSv1.1'
+postconf -P 'submissions/inet/smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3,!TLSv1,!TLSv1.1'
+ +

OPTIONAL - submission with mandatory STARTTLS

+

Having configured submission over TLS on port 465 this step is optional. +STARTTLS is considered by some to be less secure than full-session TLS and +may be vulnerable to exploitation.

+ +
postconf -M "submission/inet=submission inet n - y - - smtpd"
+postconf -P "submission/inet/smtpd_tls_security_level=encrypt"
+postconf -P 'submission/inet/smtpd_tls_protocols=!SSLv2,!SSLv3,!TLSv1,!TLSv1.1'
+postconf -P 'submission/inet/smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3,!TLSv1,!TLSv1.1'
+postconf -P "submission/inet/smtpd_sasl_auth_enable=yes"
+postconf -P "submission/inet/smtpd_tls_auth_only=yes"
+postconf -P "submission/inet/syslog_name=postfix/submission"
+postconf -P "submission/inet/smtpd_helo_restrictions="
+postconf -P "submission/inet/smtpd_client_restrictions=permit_sasl_authenticated,reject"
+postconf -P "submission/inet/smtpd_helo_restrictions="
+postconf -P "submission/inet/smtpd_sender_restrictions=reject_sender_login_mismatch"
+postconf -P "submission/inet/smtpd_recipient_restrictions=reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_sasl_authenticated,reject"
+
+ +

SpamAssassin Configuration

+

Finally, this command tells Postfix how to interact with SpamAssassin.

+ +
postconf -M "spamassassin/unix=spamassassin unix - n n - - pipe user=debian-spamd argv=/usr/bin/spamc --socket=/var/run/spamd.sock -e /usr/sbin/sendmail -oi -f \${sender} \${recipient}" 
+ +

Dovecot Configuration

+

Dovecot configuration is usually split up into many different files under +/etc/dovecot/conf.d/ but here will be doing all of the +configuration in the primary config file +/etc/dovecot/dovecot.conf. Open that file with your editor +of choice, clear all of its contents, and then replace it with the following.

+ +
# /etc/dovecot/conf.d/10-auth.conf
+disable_plaintext_auth = yes
+auth_username_format = %n
+auth_mechanisms = plain
+userdb {
+	driver = passwd
+}
+passdb {
+	driver = pam
+}
+
+# /etc/dovecot/conf.d/10-mail.conf
+mail_location = maildir:~/Mail:INBOX=~/Mail/Inbox:LAYOUT=fs
+namespace inbox {
+	type = private
+	prefix = 
+	separator = /
+	inbox = yes
+	subscriptions = yes
+	list = yes
+}
+
+# /etc/dovecot/conf.d/10-master.conf
+service imap-login {
+# Run login processes in high-security mode (see: LoginProcess.txt in dovecot docs)
+service_count = 1
+# Disable unencrypted IMAP by setting port for plain IMAP to 0
+	inet_listener imap {
+		port = 0
+	}
+	inet_listener imaps {
+		port = 993
+		ssl = yes
+	}
+}
+
+# Allow postfix to use dovecot SASL
+service auth {
+	unix_listener /var/spool/postfix/private/auth {
+		mode = 0660
+		user = postfix
+		group = postfix
+	}
+}
+
+# /etc/dovecot/conf.d/10-ssl.conf
+ssl = required
+ssl_key = </etc/letsencrypt/live/mail.example.com/privkey.pem
+ssl_cert = </etc/letsencrypt/live/mail.example.com/fullchain.pem
+ssl_client_ca_dir = /etc/ssl/certs
+ssl_dh = </usr/share/dovecot/dh.pem
+
+# Mozilla intermediate compatibility
+ssl_min_protocol = TLSv1.2
+ssl_cipher_list = ECDHE+ECDSA+AESGCM:ECDHE+aRSA+AESGCM:ECDHE+ECDSA+CHACHA20:ECDHE+aRSA+CHACHA20:DHE+aRSA+AESGCM:!aNULL:!eNULL
+
+ssl_prefer_server_ciphers = yes
+ssl_client_require_valid_cert = yes
+
+
+# /etc/dovecot/conf.d/15-lda.conf
+protocol lda {
+	mail_plugins = \$mail_plugins sieve
+}
+
+# /etc/dovecot/conf.d/15-mailboxes.conf
+namespace inbox {
+	mailbox Sent {
+			special_use = \Sent
+			auto = subscribe
+	}
+	mailbox Trash {
+			special_use = \Trash
+			auto = create
+			autoexpunge = 30d
+	}
+	mailbox Drafts {
+			special_use = \Drafts
+			auto = subscribe
+	}
+	mailbox Spam {
+			special_use = \Junk
+			auto = create
+			autoexpunge = 30d
+	}
+	mailbox Archive {
+			special_use = \Archive
+			auto = create
+	}
+}
+
+# /etc/dovecot/conf.d/20-imap.conf
+imap_capability = +SPECIAL-USE
+
+# /etc/dovecot/conf.d/90-sieve.conf
+plugin {
+	sieve = ~/.dovecot.sieve
+	sieve_default = /var/lib/dovecot/sieve/default.sieve
+	sieve_global = /var/lib/dovecot/sieve/
+}
+ +

Then create the default sieve filtering script at +/var/lib/dovecot/sieve/default.sieve

+
require ["fileinto", "mailbox"];
+/*
+* Discard mail that has a spam score greater than or equal to 10
+*/
+if header :contains "X-Spam-Level" "**********" {
+	discard;
+	stop;
+}
+/*
+* Discard messages marked as infected by a virus scanner
+*/
+if header :contains "X-Virus-Scan" "infected" {
+	discard;
+	stop;
+}
+/*
+* If message is marked as spam (and falls below discard threshold) put into spam mailbox
+*/
+if header :contains "X-Spam-Flag" "YES" {
+	fileinto "Spam";
+}
+ +

And compile the script

+ +
sievec /var/lib/dovecot/sieve/default.sieve
+ + +

Finally, configure PAM authentication for dovecot at +/etc/pam.d/dovecot. Append these changes leaving any include +statements intact.

+
auth    required        pam_unix.so
+account required        pam_unix.so
+ +

OpenDKIM

+

DKIM is a mail-verification method that cryptographically signs mail +to allow receivers to verify the authenticity of the sender. Our mail server +will use DKIM to validate signatures on incoming mail and sign outgoing mail. DKIM +requires a public key to be published via DNS, which will be done near the end of +the guide.

+ +

Start by generating the DKIM key

+ +
opendkim-genkey -D /etc/dkimkeys -d example.com -s mail
+chown opendkim: /etc/dkimkeys/*
+chmod 600 /etc/dkimkeys/*
+mv /etc/dkimkeys/mail.private /etc/dkimkeys/mail.pem
+ +

Here we make a directory for the opendkim socket inside the postfix chroot and +make it accessible to the postfix user.

+ +
mkdir /var/spool/postfix/opendkim
+chmod 770 /var/spool/postfix/opendkim
+chown opendkim:opendkim /var/spool/postfix/opendkim
+usermod -aG opendkim postfix
+ +

Edit the configuration file at /etc/opendkim.conf +to be as follows:

+ +
On-BadSignature		reject
+On-Security		reject
+Syslog			yes
+SyslogSuccess		yes
+LogResults		yes
+Canonicalization		simple
+Mode			sv
+OversignHeaders		From
+Domain			example.com
+Selector			mail
+KeyFile			/etc/dkimkeys/mail.pem     
+UserID			opendkim
+UMask			007
+Socket			local:/var/spool/postfix/opendkim/opendkim.sock
+PidFile			/run/opendkim/opendkim.pid
+TemporaryDirectory		/run/opendkim
+InternalHosts		127.0.0.1
+TrustAnchorFile		/usr/share/dns/root.key
+RequireSafeKeys		True
+AlwaysAddARHeader		True
+
+ +

OpenDMARC

+

DMARC is another mail-verification technology that provides verification of the +address seen by end-users and either or both of SPF and DKIM. + +

Like with OpenDKIM, we need to make a directory inside the postfix chroot +for the socket and assign proper permissions.

+
mkdir /var/spool/postfix/opendmarc
+chmod 770 /var/spool/postfix/opendmarc
+chown opendmarc:opendmarc /var/spool/postfix/opendmarc
+usermod -aG opendmarc postfix
+
+ +

Now we write the configuration file at /etc/opendmarc.conf

+ +
PidFile 		/run/opendmarc/opendmarc.pid
+PublicSuffixList	/usr/share/publicsuffix/public_suffix_list.dat
+RejectFailures  	True
+Socket  		local:/var/spool/postfix/opendmarc/opendmarc.sock
+Syslog  		True
+SyslogFacility  	mail
+UMask   		002
+UserID  		opendmarc
+HistoryFile	/var/run/opendmarc/opendmarc.hist
+SPFIgnoreResults	True
+SPFSelfValidate	True
+
+ +

Then create the history file and set permissions.

+ +
touch /var/run/opendmarc/opendmarc.hist
+chown opendmarc:opendmarc /var/run/opendmarc/opendmarc.hist
+chmod 664 /var/run/opendmarc/opendmarc.hist
+
+ +

Now that both OpenDKIM and OpenDMARC are configured we can define them as milters +in postfix. This will tell postfix to route mail through one or both of these milters +depending on whether it is incoming or outgoing.

+ +
postconf -P "smtpd/pass/smtpd_milters=unix:opendkim/opendkim.sock,unix:opendmarc/opendmarc.sock"
+postconf -P "submissions/inet/smtpd_milters=unix:opendkim/opendkim.sock"
+# If you enabled submission on port 587 run this too
+postconf -P "submission/inet/smtpd_milters=unix:opendkim/opendkim.sock"
+
+ +

Postgrey

+

Postgrey implements a spam-filter technique known as greylisting, which +always rejects mail on the first try and for a period of time afterwards known +as the greylist period. The idea behind this being that legitimate senders will +send the mail again later, while spammers, in a rush to send as many messages as +possible before being blacklisted, will not.

+ +

Postgrey ships with an extensive whitelist domains that are known +to cause issues (mainly large providers that constantly send from different +addresses). This whitelist file is located at +/etc/postgrey/whitelist_clients and can be appended to include +any domain you do not wish to be subject to greylisting.

+ +

The configuration needed here is minimal, just open +/etc/default/postgrey and make these changes

+ +
POSTGREY_OPTS="--unix=/var/spool/postfix/private/postgrey --privacy"
+POSTGREY_TEXT="Greylisted - see https://www.greylisting.org"
+ +

And then enable the service

+ +
systemctl enable --now postgrey
+ +

Policyd-SPF

+

SPF is yet another mail-verification technology that uses DNS records to +delegate specific servers as being authorized to send mail for the domain +(and implicitly all other servers as unauthorized). Policyd-SPF will perform +SPF checking of received mail and reject mail that fails SPF verfication.

+ +

First, tell postfix how to access Policyd-SPF

+ +
postconf -e "policyd-spf_time_limit = 3600"
+postconf -M "policyd-spf/unix=policyd-spf unix - n n - 0 spawn user=policyd-spf argv=/usr/bin/policyd-spf"
+ +

And then edit the configuration file at +/etc/postfix-policyd-spf-python/policyd-spf.conf

+ +
debugLevel = 1
+TestOnly = 1
+HELO_reject = Fail
+Mail_From_reject = Fail
+Header_Type = AR
+# These settings increase false-positive risk
+# Comment them if you want to reduce that risk
+PermError_reject = True
+TempError_Defer = True
+ + +

SpamAssassin

+

SpamAssassin is a spam-filter that will scan all received mail and assign +a spam score based on configured rules. SpamAssassin is much heavier and more +resource-intensive than any of the previous spam-filtering/verification programs +we have configured. The postfix spam-filtering philosophy emphasizes the use +of lightweight checks before passing to an external content filter such as +SpamAssassin. Ideally, non-legitimate mail will have already been caught by one +of the previous methods, and SpamAssassin will only have to operate on a much +smaller subset of the mail that is sent to our server.

+ +

We have actually already told postfix to use SpamAssassin as a content filter +so in this section we just need to edit the configuration file +/etc/spamassassin/local.cf.

+ +
# Clearly indicate message is spam to user
+rewrite_header Subject *****SPAM*****
+rewrite_header From *****SPAM*****
+
+# Set required score to be marked as spam, 5.0 is default.
+# Lower to make policy more strict or raise to be more lenient.
+required_score 5.0
+
+# Attach original messages as text/plain instead of message/rfc822 to spam reports
+report_safe 2
+
+Do not implicitly trust mail based on IP address except localhost
+trusted_networks       127.0.0.1/32
+
+ +

And finally make a few changes to the defaults file at +/etc/default/spamassassin

+ +
OPTIONS="--listen /var/run/spamd.sock --max-children 5"
+PIDFILE=/var/run/spamd.pid
+CRON=1
+ +

Wrapping Up

+

At this point we have done all of the necessary configuration of the mail +server programs. We have just a few more minor tasks before your mail server +is operational.

+ +

Configure Firewall

+

We need to open the proper ports in the firewall. This example uses UFW.

+ +
ufw allow 25 comment "smtp"
+ufw allow 465 comment "submission over TLS"
+# Run this next command only if you enabled submission on port 587
+ufw allow 587 comment "mail submission"
+ufw allow 993 comment "IMAP over TLS"
+ufw reload
+ +

Restart services

+

Now let's restart the services to pick up any configuration changes.

+ +
systemctl restart postfix
+systemctl restart dovecot
+systemctl restart opendkim
+systemctl restart opendmarc
+systemctl enable --now spamassassin
+systemctl restart spamassassin
+systemctl restart postgrey
+ +

DNS Entries

+

Finally, we needs to set some required DNS records to enable mail flow and +verification. Begin by logging into your registrar or DNS host and editing +your DNS records.

+ +

A Record

+

If you did not set a wildcard A record earlier, you will need to set one now +for mail. +Alternatively, if you are running the mail server on the same server as your +website, you may want to instead make a CNAME record pointing mail to www.

+ +

MX Record

+

MX records tell servers attempting to send you mail where to send it. Open the +MX records section on your registrar and add a new record. An MX +record consists of a priority and a destination. Set the priority to 10 and the +destination to mail, or whatever your subdomain for this mail +server is. The host value can be left blank or may need to be set to "@" +depending on your registrar.

+ +

DKIM TXT Record

+

Now we will set the three TXT records we need. Open the TXT records tab on +your registrar.

+ +

We'll set the DKIM record first. The command we ran to +generate our DKIM keys also generates a DNS record for us which will be helpful +here. Print that to the screen with:

+ +
cat /etc/dkimkeys/mail.txt
+ +

You should get a lengthy output that looks something like the following. The +bolded portion is the value.

+ +
mail._domainkey	IN	TXT	( "v=DKIM1; h=sha256; k=rsa; "
+	  "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz50PSYL0Ob+OlF/0B77rwlzLe7zF6JKnxQNtMqcOCZ0Dar2FPhSUSz1FR0YmNuoShjMogdgKeojIzgRUqwK5GZ5Lz456qiXWkfAtLPc6UQ/WPoyEBGbJpRBYPGWdN4VoNcHkk/I4csvXW6MOI55ghPOwDmootPkCzNPR6gmNAXMe0duS4Lb+bIjy9QMOxGYVUaQ/b+7xar+fWw"
+	  "bA3DjQa3jTLCydzzJpjEMfVaKqNhQ4N+ve7O2Mb3LF5k5B977mtok/6POjVG5HY8g6Pba+GzMFItR6nJO5EE2fyfv6cNbRLsZiM+WQmqvDBst5ejaeapy86F5PdJFlX/TUgXjtuwIDAQAB" )  ; ----- DKIM key mail for example.com
+ +

You can cleanup the spacing of the value as your registrar should automatically +handle any needed splitting of the record. The parts you need to paste into your +registrar's web interface should then look like this.

+ +
# Name/Host 
+mail._domainkey
+# TXT Value
+"v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz50PSYL0Ob+OlF/0B77rwlzLe7zF6JKnxQNtMqcOCZ0Dar2FPhSUSz1FR0YmNuoShjMogdgKeojIzgRUqwK5GZ5Lz456qiXWkfAtLPc6UQ/WPoyEBGbJpRBYPGWdN4VoNcHkk/I4csvXW6MOI55ghPOwDmootPkCzNPR6gmNAXMe0duS4Lb+bIjy9QMOxGYVUaQ/b+7xar+fWwbA3DjQa3jTLCydzzJpjEMfVaKqNhQ4N+ve7O2Mb3LF5k5B977mtok/6POjVG5HY8g6Pba+GzMFItR6nJO5EE2fyfv6cNbRLsZiM+WQmqvDBst5ejaeapy86F5PdJFlX/TUgXjtuwIDAQAB"
+ +

DMARC TXT Record

+

The DMARC record should be as follows:

+ +
# Name/Host 
+_dmarc
+# Value 
+"v=DMARC1; p=reject; rua=mailto:dmarc@example.com; fo=1"
+
+ +

SPF Record

+

Your SPF record will look like this. Remember to replace +mail.example.com with your server name.

+ +
# Name/Host 
+@
+# Value
+"v=spf1 a:mail.example.com -all"
+
+ +

PTR Record

+

Many mail servers rely on PTR records for verification purposes so we need +to make sure our server's IP address resolves to the proper domain name. If +your mail server is residing on a VPS, you will need to add this record on your +VPS provider's interface, consult their documentation for details.

+ +

Creating your own Mail User

+

Your mail server is now up and running. Let's create an email for you to +receive mail.

+ +
useradd --shell /usr/sbin/nologin --create-home --user-group user
+echo "user@example.com	user" >> /etc/postfix/login_maps
+echo "user	user" >> /etc/postfix/local_maps
+postmap /etc/postfix/login_maps
+postmap /etc/postfix/local_maps
+postfix reload
+
+ +

I have a script available for adding and removing users that you can find +here. + +

Connecting From a Mail Client

+

When connecting your account to a mail client you need to use these settings.

+ + +

+


+Consider donating if this article was useful. +[BTC] +

+
+ + + + diff --git a/articles/mdadm-raid.html b/articles/mdadm-raid.html new file mode 100644 index 0000000..dd2a014 --- /dev/null +++ b/articles/mdadm-raid.html @@ -0,0 +1,120 @@ + + + + + + + + + + +

Linux Software RAID

+
+

mdadm is a tool that allows for creation and + management of software RAID arrays on Linux. Creating an array + is a rather straightforward process.

+ +

Install packages

+

The only package needed is mdadm itself

+
apt install mdadm
+ +

Partition disks

+

We'll need to parition the disks to be used in the array before + creating it. This isn't anything complicated, we will just be + creating a single partition using all the space on each disk.

+ +

Use lsblk to get a list of disks attached to your system.

+ + lsblk command + +

Then use fdisk to edit the partition table of the + first disk. In my case this would be /dev/sdb. + Be sure that you are selecting the correct disk as selecting the + wrong one can result in data being lost.

+ +
fdisk /dev/sdb
+ +

Use g to create a new GUID partition table. + Use n to create a new partition, and then just press + enter at all of the prompts to accept the defaults. Finally use + w to write the changes. You can use lsblk again + to verify the change and you should see that /dev/sdb now has a + partition /dev/sdb1.

+ + fdisk command + +

Repeat this process for your other disks before continuing.

+ + +

Create the array

+

Creating the array is done with a single command, but takes just a + bit of planning.

+ + +
mdadm --create /dev/md0 --level=5 --raid-devices=3 /dev/sdb1 /dev/sdc1 /dev/sdd1 --spare-devices=1 /dev/sde1
+ +

After creating the array run the following command to get details + and the status of the array. It will take a bit to initialize the + array, you will know this is done when the state is clean. You do not + need to wait for the array to completely intialize to continue.

+ +
mdadm --detail /dev/md0
+ +

Take note of the UUID and name values as we will need them in the + next step.

+ +

Before moving on we need to make a filesystem on the array. I'm + going to make a simple EXT4 filesystem here.

+ +
mkfs.ext4 /dev/md0
+ + +

Configuration Files

+ +

Open the mdadm configuration file at + /etc/mdadm/mdadm.conf and append this line. Replace + uuid and name with the values you got when running + mdadm --detail, replace 0 whatever ID you chose.

+ +
ARRAY /dev/md0 metadata=1.2 UUID=uuid name=name
+ +

Optionally, create an /etc/fstab entry for + automounting of the array. Replace /mnt/raid with the directory + where you want to mount the array. If you made a filesystem other than + ext4 make sure to change that value.

+ +
/dev/md0 /mnt/raid ext4 defaults 0 1
+ +

+


+Consider donating if this article was useful. +[BTC] +

+
+ + + + diff --git a/articles/mutt.html b/articles/mutt.html new file mode 100644 index 0000000..962ae33 --- /dev/null +++ b/articles/mutt.html @@ -0,0 +1,27 @@ + + + + + + + + + + +

Mutt - Terminal Email Client

+
+
+

+


+Consider donating if this article was useful. +[BTC] +

+ + + + + diff --git a/articles/pam-tfa.html b/articles/pam-tfa.html new file mode 100644 index 0000000..7bdc551 --- /dev/null +++ b/articles/pam-tfa.html @@ -0,0 +1,157 @@ + + + + + + + + + + +

PAM OATH Two Factor Authentication

+
+

In this article we are going to look at configuring two factor + authentication via PAM using OATH. This is a simple and private way + to increase the security of your systems. Even if you are not familiar + with the term, it is likely that you + have used OATH before. OATH (specifically TOTP) is the rotating 6 + digit code that you get from scanning a QR code when setting up 2FA + on an account.

+ +

This example will show how to configure 2FA for SSH logins to a + server, but can easily be generalized to cover other programs or + even all authentication on a system. The two factors here will be + public key authentication and then the OATH/TOTP code. + It is highly recommended that you remain SSHd into your server + until after testing to avoid locking yourself out in the event + of a configuration error.

+ +

Install Packages

+

You only need to install a single package on the server side.

+ +
apt install libpam-oath
+ +

On the client machine that will be SSHing to the server install + these two packages.

+ +
apt install oathtool qrencode
+ +

Configure OATH

+

Create the OATH configuration file /etc/users.oath. + This file will contain the OATH secret keys so permissions need to be + set to only allow the root user to view it.

+ +
touch /etc/users.oath
+chown root: /etc/users.oath
+chmod 600 /etc/users.oath
+ +

Generate a secret key for the TOTP. Treat this secret key as you + would your SSH or GPG private key. Anyone who has this key will be able + to generate the code needed to authenticate.

+ +
openssl rand -hex 10
+ +

Now we define the TOTP configuration for our user. If you were + setting this up for multiple users you would make one entry per line. + Open /etc/users.oath and add this line. + user is the username of the account you will SSH into. + Replace the long string of numbers and letters with the secret key + you just generated.

+ +
HOTP/T30/6 user - 00112233445566aabbcc
+ + +

Configure PAM

+

Now we need to tell PAM to use OATH to authenticate sshd. Do that + by opening /etc/pam.d/sshd and adding the following + line to the top of the file.

+ +
auth sufficient pam_oath.so usersfile=/etc/users.oath window=30 digits=6
+ +

This tells PAM to consider a valid 6 digit code as fully authenticated + and to skip any other processing that may normally occur, such as + requesting a password.

+ +

Configure SSHD

+

We need to make a few changes to the sshd configuration to allow + OATH to work properly. Open the sshd configuration file at + /etc/ssh/sshd_config and make the following changes.

+ +
AuthenticationMethods publickey,keyboard-interactive
+PubkeyAuthentication yes
+PasswordAuthentication no
+ChallengeResponseAuthentication yes
+UsePAM yes
+ +

The AuthenticationMethods line specifically tells + sshd that a user needs to both have an authorized SSH key and know + the proper 6 digit code to login.

+ +

Restart sshd to apply the changes

+ +
systemctl restart sshd
+ +

Test the Changes

+

From your client ssh into your server as normal. Instead of + connecting as you have been, you should now see a prompt for your + one time password. You can use oathtool to get + the code. Again, replace the long string of numbers and letters + with the secret key you generated on the server.

+ +
oathtool --totp -d6 00112233445566aabbcc
+ +

Enter that 6 digit code into the prompt and you will be logged + into your server.

+ +

Now, in the unlikely event that your SSH private key is stolen, + an attacker still won't be able to access your server!

+ +

Managing your TOTP

+

You probably don't want to run the oathtool command everytime you + need your code, and while you could make an alias, that would require + storing your secret key in plaintext. Here are some better options.

+ + + +

You may also want to generate a QR code for easy setup on another + device. Rerun the same oathtool command as before with the -v flag + to get the base32 version of your secret key.

+ +
oathtool --totp -v -d6 00112233445566aabbcc
+--------------------------------
+Hex secret: 00112233445566aabbcc
+Base32 secret: AAISEM2EKVTKVO6M
+Digits: 6
+Window size: 0
+TOTP mode: SHA1
+Step size (seconds): 30
+
+ +

Then use qrencode to generate the QR code image.

+ +
qrencode -o totp.png 'otpauth://totp/user@server?secret=AAISEM2EKVTKVO6M'
+ +
+ +

+


+Consider donating if this article was useful. +[BTC] +

+ + + + + diff --git a/articles/template.html b/articles/template.html new file mode 100644 index 0000000..f908cab --- /dev/null +++ b/articles/template.html @@ -0,0 +1,27 @@ + + + + + + + + + + +

Article

+
+
+

+


+Consider donating if this article was useful. +[BTC] +

+ + + + + -- cgit v1.2.3