<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SysAdmin &#8211; Johnny Morano&#039;s Tech Articles</title>
	<atom:link href="https://jmorano.moretrix.com/tag/sysadmin/feed/" rel="self" type="application/rss+xml" />
	<link>https://jmorano.moretrix.com</link>
	<description>Ramblings of an old-fashioned space cowboy</description>
	<lastBuildDate>Wed, 08 Jun 2022 06:35:06 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.6.2</generator>

<image>
	<url>https://jmorano.moretrix.com/wp-content/uploads/2022/04/cropped-jmorano_emblem-32x32.png</url>
	<title>SysAdmin &#8211; Johnny Morano&#039;s Tech Articles</title>
	<link>https://jmorano.moretrix.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Using multipath together with mdadm on Debian</title>
		<link>https://jmorano.moretrix.com/2022/06/using-multipath-together-with-mdadm-on-debian/</link>
					<comments>https://jmorano.moretrix.com/2022/06/using-multipath-together-with-mdadm-on-debian/#respond</comments>
		
		<dc:creator><![CDATA[Johnny Morano]]></dc:creator>
		<pubDate>Wed, 08 Jun 2022 06:35:04 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[Fiber Channel]]></category>
		<category><![CDATA[mdadm]]></category>
		<category><![CDATA[multipath]]></category>
		<category><![CDATA[SysAdmin]]></category>
		<guid isPermaLink="false">https://jmorano.moretrix.com/?p=1533</guid>

					<description><![CDATA[Using multipath together with mdadm on Debian Linux requires some changes to the initrd image, otherwise mdadm might&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Using multipath together with mdadm on Debian Linux requires some changes to the initrd image, otherwise mdadm might start before multipath, leading to only one FC path being used or even failure of starting multipath (no FC paths found at all).</p>



<p>To prevent this issue, three steps are required:</p>



<ul class="wp-block-list"><li>change the order kernel modules get loaded by initrd</li><li>disable the mdadm auto-assembly of disks when initrd is loaded</li><li>generate a new initrd image </li></ul>



<p>The initrd configuration files can be found at <code>/etc/initramfs-tools</code>.</p>



<p>First define the order of module loading during boot (ensure that <code>multipath</code> is loaded before <code>mdadm</code>). Edit the file <code>/etc/initramfs-tools/modules</code> to match:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># List of modules that you want to include in your initramfs.
# They will be loaded at boot time in the order below.
#
# Syntax: module_name [args ...]
#
# You must run update-initramfs(8) to effect this change.
#
# Examples:
#
# raid1
# sd_mod
libfc
megaraid_sas
scsi_dh_alua
scsi_transport_fc
dm_multipath
dm_service_time
multipath
md_mod</pre>



<p>This starts by loading the &#8220;fiber channel libs&#8221; (<code>libfc</code>) first, followed by the MegaRAID modules, SCSI over fiber channel, <code>multipath</code> and <code>mdadm</code>.</p>



<p>Now copy the mdadm initramfs hook to <code>/etc</code> to override the default one:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">cp /usr/share/initramfs-tools/hooks/mdadm /etc/initramfs-tools/hooks/</pre>



<p>Edit the hook file in <code>/etc/initramfs-tools/hooks/mdadm </code>and add an &#8216;<code>exit 0</code>&#8216; (see line 10):</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#!/bin/sh
#
# Copyright © 2006-2008 Martin F. Krafft &lt;madduck@debian.org>,
#
2012 Michael Tokarev &lt;mjt@tls.msk.ru>
# based on the scripts in the initramfs-tools package.
# released under the terms of the Artistic Licence.
#
set -eu
exit 0
PREREQ="udev"
prereqs()
{
echo "$PREREQ"
}</pre>



<p>Disable automatic startup of the <code>mdadm</code> service:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">rm /lib/systemd/system/mdadm.service
systemctl daemon-reload
systemctl disable mdadm.service</pre>



<p>Finally, update the initrd images for all kernel versions installed:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">update-initramfs -u -k all</pre>



<p>Reboot the server to see if modules are now loaded in the correct order, and multipath is loaded and started before mdadm.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jmorano.moretrix.com/2022/06/using-multipath-together-with-mdadm-on-debian/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Managing LDAP passwords with Perl</title>
		<link>https://jmorano.moretrix.com/2022/04/managing-ldap-passwords-with-perl/</link>
					<comments>https://jmorano.moretrix.com/2022/04/managing-ldap-passwords-with-perl/#respond</comments>
		
		<dc:creator><![CDATA[Johnny Morano]]></dc:creator>
		<pubDate>Mon, 25 Apr 2022 09:30:40 +0000</pubDate>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[OpenmLDAP]]></category>
		<category><![CDATA[SysAdmin]]></category>
		<guid isPermaLink="false">https://jmorano.moretrix.com/?p=1511</guid>

					<description><![CDATA[OpenLDAP Software is an open source implementation of the Lightweight Directory Access Protocol. Many graphical interfaces are available&#8230;]]></description>
										<content:encoded><![CDATA[
<p><a href="https://openldap.org/" data-type="URL" data-id="https://openldap.org/" target="_blank" rel="noreferrer noopener">OpenLDAP</a> Software is an open source implementation of the Lightweight Directory Access Protocol.</p>



<p>Many graphical interfaces are available for managing user accounts in OpenLDAP like PHPLDAPAdmin (<a rel="noreferrer noopener" href="http://phpldapadmin.sourceforge.net/wiki/index.php/Main_Page" target="_blank">http://phpldapadmin.sourceforge.net/wiki/index.php/Main_Page</a>) or LAM (<a rel="noreferrer noopener" href="https://www.ldap-account-manager.org/lamcms/" target="_blank">https://www.ldap-account-manager.org/lamcms/</a>).</p>



<p>When generating a bulk amount of accounts with automation or just managing user details with a simple script, allows much more flexibility and can be even quicker.</p>



<p>LDAP passwords can be stored or changed by using an LDIF file. This LDIF file needs 3 required lines:</p>



<ol class="wp-block-list"><li>The &#8220;<code>dn</code>&#8221; you are about to change</li><li>the &#8220;<code>changetype</code>&#8221; set to &#8220;<code>modify</code>&#8220;</li><li>A &#8220;<code>replace</code>&#8221; line containing the field you want to change (in our case, since we are changing the password, this will be &#8220;<code>userPassword</code>&#8220;)</li></ol>



<p>Your LDAP password can be stored either in clear-text (which is not advisable) or by sending a <code>SHA-hash</code>. The <code>SHA-hash</code> must include the salt at the end and must be <code>base64</code> encoded.</p>



<p>The code snippit below will call a subroutine called <code>generate_password()</code> which comes from a previous article (<a href="https://jmorano.moretrix.com/2013/08/secure-password-generator-perl/" data-type="post" data-id="953">Secure Password Generator in Perl</a>).</p>



<p>At the end of the script, it will print out the LDIF file content, which needs to be saved to <code>change.ldif</code>. As last, it will print the <code>ldapmodify</code> command to make the actual change. You will need to know the <code>admin</code> password for this. Alternatively, you could also make this change using your own <code>dn</code> for authentication.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use Digest::SHA;
use MIME::Base64;

my $random_password = generate_password(24);
my $random_salt     = generate_password(3);

my $ctx = Digest::SHA->new;
$ctx->add($random_password);
$ctx->add($random_salt);
my $hashedPasswd = encode_base64($ctx->digest . $random_salt, '');

print "password: $random_password\n";
print "salt: $random_salt\n";
print &lt;&lt;EOF;
# LDIF
dn: uid=user1,ou=users,dc=shihai-corp,dc=at
changetype: modify
replace: userPassword
userPassword: {SSHA}$hashedPasswd
EOF

print "\n";
print q{LDAP cmd: ldapmodify -H "ldap://ldap_server01" -Z -x -W -D "cn=ldapadmin,ou=admins,dc=shihai-corp,dc=at" -f change.ldif} . "\n\n"</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://jmorano.moretrix.com/2022/04/managing-ldap-passwords-with-perl/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Libvirt guest startup issue with AppArmor</title>
		<link>https://jmorano.moretrix.com/2022/04/libvirt-guest-startup-issue-with-apparmor/</link>
					<comments>https://jmorano.moretrix.com/2022/04/libvirt-guest-startup-issue-with-apparmor/#respond</comments>
		
		<dc:creator><![CDATA[Johnny Morano]]></dc:creator>
		<pubDate>Sun, 10 Apr 2022 09:37:48 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[AppArmor]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Libvirt]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<guid isPermaLink="false">https://jmorano.moretrix.com/?p=1487</guid>

					<description><![CDATA[With AppArmor enabled on Debian/ Ubuntu systems, starting up virtual machines with libvirt can cause startup failures if&#8230;]]></description>
										<content:encoded><![CDATA[
<p>With <a href="https://apparmor.net/" data-type="URL" data-id="https://apparmor.net/" target="_blank" rel="noreferrer noopener">AppArmor</a> enabled on Debian/ Ubuntu systems, starting up virtual machines with <a href="https://libvirt.org/" data-type="URL" data-id="https://libvirt.org/" target="_blank" rel="noreferrer noopener">libvirt</a> can cause startup failures if not AppArmor is not properly configured.</p>



<p>AppArmor will write messages to the kernel log (visible with either the <code>dmesg</code> command or in <code>kernel.log</code> if available) regarding its actions.</p>



<p>If your libvirt guests are not starting up or failing, have a look at <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">dmesg</mark></code>. Example:</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="82" src="https://jmorano.moretrix.com/wp-content/uploads/2022/04/Screenshot-from-2022-04-10-11-09-15-1024x82.png" alt="" class="wp-image-1488" srcset="https://jmorano.moretrix.com/wp-content/uploads/2022/04/Screenshot-from-2022-04-10-11-09-15-1024x82.png 1024w, https://jmorano.moretrix.com/wp-content/uploads/2022/04/Screenshot-from-2022-04-10-11-09-15-300x24.png 300w, https://jmorano.moretrix.com/wp-content/uploads/2022/04/Screenshot-from-2022-04-10-11-09-15-768x62.png 768w, https://jmorano.moretrix.com/wp-content/uploads/2022/04/Screenshot-from-2022-04-10-11-09-15-850x68.png 850w, https://jmorano.moretrix.com/wp-content/uploads/2022/04/Screenshot-from-2022-04-10-11-09-15.png 1242w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>In the above example AppArmor has <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">denied</mark> (<code>apparmor="DENIED"</code>) read access (<code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">requested_mask=r</mark></code>) to the file <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">/data/vms/cluster_storage/base-os-ubuntu-focal.qcow2</mark></code>. This blocks of course the startup guest machines we have previously created in the article: <a href="https://jmorano.moretrix.com/2022/03/terraform-and-libvirtd-nodes/" data-type="post" data-id="1302">Terraform and libvirtd nodes</a>.</p>



<p>To fix the issue, edit the file: <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">/etc/apparmor.d/libvirt/TEMPLATE.qemu</mark></code></p>



<p>By default it has the following content:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#
# This profile is for the domain whose UUID matches this file.
#

#include &lt;tunables/global>

profile LIBVIRT_TEMPLATE flags=(attach_disconnected) {
  #include &lt;abstractions/libvirt-qemu>
}
</pre>



<p>In order to allow <code>libvirt</code> to use the guest image files, change the content to (or add a similar line if your file path is different):</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#
# This profile is for the domain whose UUID matches this file.
#

#include &lt;tunables/global>

profile LIBVIRT_TEMPLATE flags=(attach_disconnected) {
  #include &lt;abstractions/libvirt-qemu>
  /data/vms/cluster_storage/**.qcow2 rwk,
}
</pre>



<p>The added line (<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">line 9</mark>) will allow read (<code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">r</mark></code>), write (<code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">w</mark></code>) and lock (<code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">k</mark></code>) access to all <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">qcow2</mark></code> files in the directory <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">/data/vms/cluster_storage</mark></code>.</p>



<p>Once added, all libvirt guests will start up again without any (AppArmor) issues.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jmorano.moretrix.com/2022/04/libvirt-guest-startup-issue-with-apparmor/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>IPTables Logging in JSON with NFLOG and ulogd2</title>
		<link>https://jmorano.moretrix.com/2022/03/logging-in-iptables-with-nflog-and-ulogd2/</link>
					<comments>https://jmorano.moretrix.com/2022/03/logging-in-iptables-with-nflog-and-ulogd2/#comments</comments>
		
		<dc:creator><![CDATA[Johnny Morano]]></dc:creator>
		<pubDate>Thu, 31 Mar 2022 08:00:00 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[IPTables]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[nflog]]></category>
		<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[ulogd2]]></category>
		<guid isPermaLink="false">https://jmorano.moretrix.com/?p=1308</guid>

					<description><![CDATA[Logging with IPTables requires the use of an extra IPTables extension called NFLOG (https://manpages.debian.org/experimental/iptables/iptables-extensions.8.en.html#NFLOG) and a separate daemon&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Logging with IPTables requires the use of an extra IPTables extension called <code>NFLOG</code> (<a rel="noreferrer noopener" href="https://manpages.debian.org/experimental/iptables/iptables-extensions.8.en.html#NFLOG" target="_blank">https://manpages.debian.org/experimental/iptables/iptables-extensions.8.en.html#NFLOG</a>) and a separate daemon process, called <code>ulogd2</code> (<a rel="noreferrer noopener" href="https://www.netfilter.org/projects/ulogd/index.html" target="_blank">https://www.netfilter.org/projects/ulogd/index.html</a>). Ulogd2 reads out the packets sent to the above mentioned extension and stores them in local files or databases.</p>



<p>First, install the <code>ulogd2</code> package (example is based on Debian/ Ubuntu):</p>



<pre class="EnlighterJSRAW" data-enlighter-language="shell" data-enlighter-theme="monokai" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">apt install ulogd2
</pre>



<p>Example: log and drop packets which have an invalid state</p>



<pre class="EnlighterJSRAW" data-enlighter-language="shell" data-enlighter-theme="monokai" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># Log and drop all invalid packets                                                                                                                                                                                         
iptables -A INPUT -m conntrack --ctstate INVALID -j NFLOG --nflog-group 123 --nflog-prefix "packet with invalid state"
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
</pre>



<p>To log all those packets to a file in JSON format, <code>ulogd2</code> requires the following configuration at <code>/etc/ulogd.conf</code></p>



<pre class="EnlighterJSRAW" data-enlighter-language="ini" data-enlighter-theme="monokai" data-enlighter-highlight="" data-enlighter-linenumbers="true" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[global]                                                                                                                                                                                                           
logfile="syslog"
loglevel=3                                                                                                                                                                                                                   
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_inppkt_NFLOG.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_IFINDEX.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_IP2STR.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_IP2BIN.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_PRINTPKT.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_HWHDR.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_raw2packet_BASE.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_output_JSON.so"

stack=log1:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,mac2str1:HWHDR,json1:JSON

[log1]
group=123

[json1]
sync=1
file="/var/log/ulog/netfilter_log.json"</pre>



<p>After creating the configuration file, ensure that <code>ulogd2</code> is restarted and that the directory <code>/var/log/ulog</code> exists</p>



<pre class="EnlighterJSRAW" data-enlighter-language="shell" data-enlighter-theme="monokai" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">mkdir /var/log/ulog
chown ulog /var/log/ulog
systemctl restart ulogd2.service</pre>



<p>Once the above created rule matches, a JSON log line will be written to disk:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="json" data-enlighter-theme="monokai" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">tail -1 /var/log/ulog/netfilter_log.json | jq
{
  "timestamp": "2022-03-30T14:46:20.527282+0200",
  "dvc": "Netfilter",
  "raw.pktlen": 52,
  "raw.pktcount": 1,
  "oob.prefix": "packet with invalid state",
  "oob.time.sec": 1648644380,
  "oob.time.usec": 527282,
  "oob.mark": 0,
  "oob.ifindex_in": 2,
  "oob.hook": 1,
  "raw.mac_len": 14,
  "oob.family": 2,
  "oob.protocol": 2048,
  "raw.label": 0,
  "raw.type": 1,
  "raw.mac.addrlen": 6,
  "ip.protocol": 6,
  "ip.tos": 0,
  "ip.ttl": 116,
  "ip.totlen": 52,
  "ip.ihl": 5,
  "ip.csum": 41779,
  "ip.id": 16049,
  "ip.fragoff": 16384,
  "src_port": 58662,
  "dest_port": 445,
  "tcp.seq": 3872158206,
  "tcp.ackseq": 0,
  "tcp.window": 8192,
  "tcp.offset": 0,
  "tcp.reserved": 0,
  "tcp.urg": 0,
  "tcp.ack": 0,
  "tcp.psh": 0,
  "tcp.rst": 0,
  "tcp.syn": 1,
  "tcp.fin": 0,
  "tcp.res1": 0,
  "tcp.res2": 0,
  "tcp.csum": 60039,
  "oob.in": "eth0",
  "oob.out": "",
  "src_ip": "181.122.165.177",
  "dest_ip": "1.1.1.1",
  "mac.saddr.str": "94:f7:ad:4f:81:fc",
  "mac.daddr.str": "aa:aa:aa:aa:aa:aa",
  "mac.str": "aa:aa:aa:aa:aa:aa:94:f7:ad:4f:81:fc:08:00"
}</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://jmorano.moretrix.com/2022/03/logging-in-iptables-with-nflog-and-ulogd2/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Time based network access control on OpenBSD</title>
		<link>https://jmorano.moretrix.com/2022/03/time-based-network-access-control-on-openbsd/</link>
					<comments>https://jmorano.moretrix.com/2022/03/time-based-network-access-control-on-openbsd/#respond</comments>
		
		<dc:creator><![CDATA[Johnny Morano]]></dc:creator>
		<pubDate>Tue, 01 Mar 2022 13:14:17 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[OpenBSD]]></category>
		<category><![CDATA[PF]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[UNIX]]></category>
		<guid isPermaLink="false">https://jmorano.moretrix.com/?p=1293</guid>

					<description><![CDATA[Time based ACL (access control lists) features do not exist in BSD&#8217;s packet filter (PF). Having your network&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Time based ACL (access control lists) features do not exist in BSD&#8217;s packet filter (<code>PF</code>). Having your network &#8220;shut down&#8221; at certain times (for instance, allow certain network ranges or specific IP addresses only during &#8220;business hours&#8221; or a specific time range), can be achieved with a simple <code>PF</code> table and a <code>cronjob</code>.</p>



<p>First, let&#8217;s set up the <code>PF</code> table which will control the traffic. Add the following to your <code>/etc/pf.conf</code> :</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># add time block table
table &lt;time_block> { } persist
</pre>



<p>Next, create a <code>PF</code> rule which block traffic for all entries in the <code>time_block</code> table:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># block all CIDR addresses in the time block table
block in quick log from &lt;time_block> to any
</pre>



<p>Since the <code>time_block</code> table is still empty, no traffic is actually blocked.</p>



<p>The last thing to implement, is periodically manipulating the <code>time_block</code> table. This could be done by creating two <code>cronjobs</code>:</p>



<ol class="wp-block-list"><li>allow traffic at the beginning of &#8220;business hours&#8221;</li><li>block traffic at the end of &#8220;business hours&#8221;</li></ol>



<pre class="EnlighterJSRAW" data-enlighter-language="shell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">crontab -e
# Allow traffic
0 7 * * * /usr/local/scripts/allow_employees.sh > /dev/null 2>&amp;1
# Block traffic
0 17 * * * /usr/local/scripts/block_employees.sh > /dev/null 2>&amp;1
﻿</pre>



<p>The <code>allow_employees.sh</code> script will allow certain network ranges by ensuring those are removed from the <code>time_block</code> table:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="shell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#!/bin/sh

/sbin/pfctl -Td -t time_block 10.1.0.0/24
/sbin/pfctl -Td -t time_block 10.2.0.0/24
</pre>



<p>The <code>block_employees.sh</code> script will do the exact opposite: it will add ranges to the <code>time_block</code> table so that their network access will be blocked by the firewall:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="shell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#!/bin/sh

/sbin/pfctl -Ta -t time_block 10.1.0.0/24
/sbin/pfctl -Ta -t time_block 10.2.0.0/24
</pre>



<p>Finally deploy your new PF rules (first test them!)</p>



<pre class="EnlighterJSRAW" data-enlighter-language="shell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pfctl -nf /etc/pf.conf
pfctl -f /etc/pf.conf</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://jmorano.moretrix.com/2022/03/time-based-network-access-control-on-openbsd/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Block countries on OpenBSD using pf</title>
		<link>https://jmorano.moretrix.com/2022/03/block-countries-on-openbsd-using-pf/</link>
					<comments>https://jmorano.moretrix.com/2022/03/block-countries-on-openbsd-using-pf/#respond</comments>
		
		<dc:creator><![CDATA[Johnny Morano]]></dc:creator>
		<pubDate>Tue, 01 Mar 2022 12:28:09 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[OpenBSD]]></category>
		<category><![CDATA[PF]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[UNIX]]></category>
		<guid isPermaLink="false">https://jmorano.moretrix.com/?p=1291</guid>

					<description><![CDATA[Same as in the previous article, full countries can be easily blocked on OpenBSD firewall using the pf&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Same as in the <a href="https://jmorano.moretrix.com/2022/03/block-countries-using-iptables/" data-type="post" data-id="1285">previous article</a>, full countries can be easily blocked on OpenBSD firewall using the <code>pf</code> command and <a rel="noreferrer noopener" href="https://ipdeny.com/" target="_blank">https://ipdeny.com/</a>.</p>



<p>The zone files provided by <a rel="noreferrer noopener" href="https://ipdeny.com/" target="_blank">https://ipdeny.com/</a> need to be stored locally. A simple way to achieve this is by having a <code>cronjob</code> downloading those periodically (for instance once per day):</p>



<pre class="EnlighterJSRAW" data-enlighter-language="shell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#!/bin/sh

# download the latest country zone files
curl -s https://www.ipdeny.com/ipblocks/data/countries/ru.zone > /etc/ru.zone
curl -s https://www.ipdeny.com/ipblocks/data/countries/cn.zone > /etc/cn.zone
﻿</pre>



<p>We store them directly to <code>/etc</code> in the above example.</p>



<p>In the <code>/etc/pf.conf</code>, first add a table based on the files you have generated with the above statements:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># add a bad hosts table based on local disk text files
# one CIDR per line
table &lt;badhosts> persist file "/etc/ru.zone" file "/etc/cn.zone"
</pre>



<p>In the above example, we have created a table called <code>badhosts</code> based on two local files.</p>



<p>Finally we need some rules which actually blocks from and to these network ranges, an example <code>PF</code> block rule could be:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># block bad IP addresses
block from &lt;badhosts> to any
block from any to &lt;badhosts>
</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://jmorano.moretrix.com/2022/03/block-countries-on-openbsd-using-pf/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Block countries using IPtables and IPDeny.com</title>
		<link>https://jmorano.moretrix.com/2022/03/block-countries-using-iptables/</link>
					<comments>https://jmorano.moretrix.com/2022/03/block-countries-using-iptables/#comments</comments>
		
		<dc:creator><![CDATA[Johnny Morano]]></dc:creator>
		<pubDate>Tue, 01 Mar 2022 07:12:28 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[IPTables]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SysAdmin]]></category>
		<guid isPermaLink="false">https://jmorano.moretrix.com/?p=1285</guid>

					<description><![CDATA[Certain server setups do not require access for all countries or just want to block certain countries since&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Certain server setups do not require access for all countries or just want to block certain countries since they are know for their malicious activity.</p>



<p>One simple (not full bullet-proof) way of doing this, is by setting up block rules on firewall level, which can be achieved on Linux servers with <code>iptables</code> and zone files of <a rel="noreferrer noopener" href="https://www.ipdeny.com/" target="_blank">https://www.ipdeny.com/</a>. These zone files contain the network ranges assigned to a specific country.</p>



<p>The network ranges are fed to a tool called <code>ipset</code>, which sets up of hash map that can be easily used within <code>iptables</code> rules.</p>



<p>On Debian/Ubuntu systems, <code>ipset</code> can be installed with the <code>apt</code> command:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="shell" data-enlighter-theme="monokai" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">apt install ipset</pre>



<p>Next, create an iptables chain called &#8220;<code>blocked_countries</code>&#8220;, to which we will add rules afterwards. Add this chain to the beginning of the <code>INPUT</code> and <code>FORWARD</code> chain, to have early blocking in your ruleset.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="shell" data-enlighter-theme="monokai" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">iptables -N blocked_countries
iptables -I INPUT -j blocked_countries -m comment --comment "Blocked countries"
iptables -I FORWARD -j blocked_countries -m comment --comment "Blocked countries"</pre>



<p>Finally, create a shell script which will download the required zone files from <a rel="noreferrer noopener" href="https://ipdeny.com/" target="_blank">https://ipdeny.com/</a> and which feeds them to <code>ipset</code>. The  example script will try to block the countries China, Russia and Belarus:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="shell" data-enlighter-theme="monokai" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#!/bin/bash

COUNTRIES=('cn' 'ru' 'by')

for COUNTRY in "${COUNTRIES[@]}"; do
    ipset create "countries_${COUNTRY}" hash:net
done

iptables -v -F blocked_countries

for i in "${COUNTRIES[@]}"; do
    echo "Ban IP of country ${i}"
    ipset flush "countries_${i}"


    for IP in $(wget -O - https://www.ipdeny.com/ipblocks/data/countries/${i}.zone)
    do
        ipset add "countries_${i}" $IP
    done
    iptables -I blocked_countries   -m set --match-set "countries_${i}" src  -j LOGDROP -m comment   --comment "Block .${i}"
done
﻿</pre>



<p>You can check the <code>blocked_countries</code> chain if packets are being blocked by your new rules:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="shell" data-enlighter-theme="monokai" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">iptables -v -n -L blocked_countries 
# Warning: iptables-legacy tables present, use iptables-legacy to see them
Chain blocked_countries (2 references)
 pkts bytes target     prot opt in     out     source               destination         
    2   104 LOGDROP    all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set countries_by src /* Block .by */
 2182  155K LOGDROP    all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set countries_ru src /* Block .ru */
  344 21370 LOGDROP    all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set countries_cn src /* Block .cn */
﻿</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://jmorano.moretrix.com/2022/03/block-countries-using-iptables/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Install OpenBSD 6.0 on a Soekris net6501</title>
		<link>https://jmorano.moretrix.com/2016/12/install-openbsd-6-0-on-a-soekris-net6501/</link>
					<comments>https://jmorano.moretrix.com/2016/12/install-openbsd-6-0-on-a-soekris-net6501/#respond</comments>
		
		<dc:creator><![CDATA[Johnny Morano]]></dc:creator>
		<pubDate>Tue, 27 Dec 2016 11:38:18 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[OpenBSD]]></category>
		<category><![CDATA[Firewall]]></category>
		<category><![CDATA[Installation]]></category>
		<category><![CDATA[Soekris]]></category>
		<category><![CDATA[SysAdmin]]></category>
		<guid isPermaLink="false">http://jmorano.moretrix.com/?p=1234</guid>

					<description><![CDATA[Recently I bought a Soekris net6501 to build a home network in my new house.Things you need before&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Recently I bought a Soekris net6501 to build a home network in my new house.<br />Things you need before you start:</p>



<ul class="wp-block-list"><li>USB / mSSD drive to install OpenBSD on</li><li>USB drive to boot from</li><li>Serial cable for the initial installation</li></ul>



<p>First go to a mirror and download the amd64 OpenBSD install image, which ends on the .fs extension. The one for OpenBSD 6.0 is called &#8216;install60.fs&#8217;.</p>



<p>The installation procedure will use an USB stick to boot the installation process.<br />The USB stick itself was created on a Linux Desktop system, using dd. There are many ways to get the install image on an USB stick. Google if you are not using a Linux desktop.</p>



<p>I downloaded the install image to my &#8216;Downloads&#8217; folder, and the USB stick was on /dev/sdb</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">dd if=./Downloads/install60.fs of=/dev/sdb bs=1024k</pre>



<p>Once the USB stick/ disk is ready, insert it in your Soekris net6501.</p>



<p>Now prepare your terminal console. I&#8217;ve used Minicom for this purpose, but any kind of terminal emulation program can be used.</p>



<p>Execute the following on the command line:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">minicom -D /dev/ttyUSB0 -b 19200 # no software or hardware flow control</pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Important to note is:<br />&#8211; The baudrate must be set to <mark style="background-color:#fcb900" class="has-inline-color">19200 baud</mark><br />&#8211; You must <mark style="background-color:#fcb900" class="has-inline-color">disable software and/ or hardware flow control</mark></p></blockquote>



<p>Once connected with the serial console cable, plug in the power cable to your Soekris so that it can be boot up.</p>



<p>At the boot prompt, configure the installation image to send its output to the serial console.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Using drive 1, partition 3.
Loading.........
probing: pc0 com0 pci mem[620K 1022M a20=on]
disk: hd0+* hd1+ hd2*
&amp;gt;&amp;gt; OpenBSD/i386 BOOT 3.29
boot&amp;gt; stty com0 19200
boot&amp;gt; set tty com0
switching console to com0
&amp;gt;&amp;gt; OpenBSD/i386 BOOT 3.29
boot&amp;gt; bsd 
</pre>



<p>There are two commands that must be executed at the boot prompt:<br />&#8211; <span class="lang:sh decode:true  crayon-inline "><code>stty com0 19200</code></span><br />&#8211; <span class="lang:sh decode:true  crayon-inline "><code>set tty com0</code></span></p>



<p>After the serial console options have been set, boot the kernel by typing <span class="lang:sh decode:true  crayon-inline "><code>bsd</code></span> and hiting <code>ENTER</code></p>



<p>The first steps are to configure the network interfaces.<br />Please also make sure you have enabled sshd, so that after the installation you can access the firewall without using the serial console cable.</p>



<p>The rest of the installation won&#8217;t be covered here.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jmorano.moretrix.com/2016/12/install-openbsd-6-0-on-a-soekris-net6501/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>OSSEC: building an OpenBSD package</title>
		<link>https://jmorano.moretrix.com/2016/03/ossec-building-an-openbsd-package/</link>
					<comments>https://jmorano.moretrix.com/2016/03/ossec-building-an-openbsd-package/#comments</comments>
		
		<dc:creator><![CDATA[Johnny Morano]]></dc:creator>
		<pubDate>Tue, 15 Mar 2016 07:28:29 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[OpenBSD]]></category>
		<category><![CDATA[HIDS]]></category>
		<category><![CDATA[OSSEC]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SysAdmin]]></category>
		<guid isPermaLink="false">http://jmorano.moretrix.com/?p=1101</guid>

					<description><![CDATA[OSSEC is an Open Source Host-based Intrusion Detection System that performs log analysis, file integrity checking, policy monitoring,&#8230;]]></description>
										<content:encoded><![CDATA[
<p><a title="OSSEC Website" href="http://www.ossec.net/" target="_blank" rel="noopener">OSSEC</a> is an Open Source Host-based Intrusion Detection System that performs log analysis, file integrity checking, policy monitoring, rootkit detection, real-time alerting and active response.</p>



<p>It runs on most operating systems, including Linux, MacOS, Solaris, HP-UX, AIX and OpenBSD.</p>



<p>There is no OSSEC package available on the OSSEC website or in the OpenBSDs ports repositry, so I&#8217;ve decided to create an OpenBSD on my own.<br />OpenBSD packages are pretty easy to create and are very useful when installing, upgrading or deleting software on a server.</p>



<p>One of the disadvantages when creating an OpenBSD package, is that you will need to have X11 installed on your OpenBSD system.<br />In the following example I have used <a href="http://openbsd.org" target="_blank" rel="noopener">OpenBSD 5.8</a> to create a package for <a href="http://ossec.github.io/" target="_blank" rel="noopener">OSSEC 2.8.2</a> (OSSEC 2.8.3 doesn&#8217;t compile on OpenBSD 5.8)</p>



<h2 class="wp-block-heading">Step 1: Prerequisites</h2>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">cd /tmp
wget http://ftp.eu.openbsd.org/pub/OpenBSD/5.8/amd64/xbase58.tgz 
wget http://ftp.eu.openbsd.org/pub/OpenBSD/5.8/amd64/xshare58.tgz
wget http://ftp.eu.openbsd.org/pub/OpenBSD/5.8/amd64/comp58.tgz
tar -C / -xzvphf xbase58.tgz
tar -C / -xzvphf xshare58.tgz
tar -C / -xzvphf comp58.tgz

cd /tmp
ftp http://ftp.eu.openbsd.org/pub/OpenBSD/$(uname -r)/ports.tar.gz
ftp http://ftp.eu.openbsd.org/pub/OpenBSD/$(uname -r)/SHA256.sig
signify -Cp /etc/signify/openbsd-$(uname -r | cut -c 1,3)-base.pub -x SHA256.sig ports.tar.gz

cd /usr
tar xzf /tmp/ports.tar.gz</pre>



<p>You will also need a compiler:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pkg_add gcc</pre>



<h2 class="wp-block-heading">Step 2: Download and repack the source</h2>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">ossec_version="2.8.2"
cd /usr/src
wget https://github.com/ossec/ossec-hids/archive/${ossec_version}.tar.gz 
mv ${ossec_version}.tar.gz ossec-hids-${ossec_version}.tar.gz 
tar xfz ossec-hids-${ossec_version}.tar.gz
cd ossec-hids-${ossec_version}
</pre>



<p>Since the Makefile for OSSEC is in the <em>src/</em> sub directory, we will create a proxy Makefile in <em>/usr/src/ossec-hids-2.8.2</em></p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">cd ossec-hids-2.8.2
vim Makefile</pre>



<p>I have actually taken the original Makefile from<em> src/</em> and narrowed it down to the following:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># Makefile
# http://www.ossec.net/hids/

none:
 @echo "Nothing selected ..."
 @echo "\"make all\" to compile everything."
 @echo "\"make server\" to build the server."
 @echo "\"make local\" to build the local."
 @echo "\"make agent\" to build the agent."
 @echo "\"make clean\" to clean anything built."

clean:
 cd src/ ; $(MAKE) clean

all:
 cd src/ ; $(MAKE) all
 
test:
 cd src/ ; $(MAKE) test

server:
 cd src/ ; $(MAKE) server

local:
 cd src/ ; $(MAKE) local

agent:
 cd src/ ; $(MAKE) agent

</pre>



<p>We will also edit the &#8216;<em>ossec-clients.sh</em>&#8216; script, because we will use this script as a start/stop script. We will have to set the path name in this script.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">vim src/init/ossec-client.sh
# LOCAL=/var/ossec
# cd ${LOCAL}
# PWD=`pwd`
DIR=/var/ossec
cd ${DIR}
</pre>



<p>And that&#8217;s the only thing we will need to change in the sources, we can now repackage it.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">cd ..
tar czf /usr/ports/distfiles/ossec-hids-2.8.2.tar.gz ossec-hids-2.8.2/
</pre>



<h2 class="wp-block-heading">Step 3: Prepare the ports directory</h2>



<p>The following steps explain how to set up a ports directory in <em>/usr/ports</em> for OSSEC, in order to build the package.<br />Custom made packages are built in<em> /usr/ports/mystuff</em>. In there, we will have to one sub directory for the package category (we will use security) and in there the package name, which in our case will be ossec-hids.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">cd /usr/ports/mystuff
mkdir -p security/ossec-hids
</pre>



<p>The configuration file for building an OpenBSD package is a Makefile. There is a template file in <em>/usr/ports/infrastructure/templates/Makefile.template</em> which can be used.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">cd security/ossec-hids
cp /usr/ports/infrastructure/templates/Makefile.template Makefile
</pre>



<p>This file of course needs editing. Not everything is required in this file, so I have narrowed the Makefile down to what I need it for:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># $OpenBSD: Makefile.template,v 1.68 2013/10/02 07:34:45 ajacoutot Exp $
# $FreeBSD/NetBSD: credit FreeBSD/NetBSD if thats where the port came from $
# Original from: credit the original author here
COMMENT =               OSSEC is an Open Source HIDS
DISTNAME =              ossec-hids-2.8.2
CATEGORIES =            security
HOMEPAGE =              http://www.ossec.net/
MAINTAINER =            Johnny Morano &amp;lt;jmorano@moretrix.com&amp;gt;;
MASTER_SITES =          https://github.com/ossec/ossec-hids/

PERMIT_PACKAGE_CDROM =  Yes
PERMIT_PACKAGE_FTP =    Yes
PERMIT_DISTFILES_FTP =  Yes

PKG_ARCH =              *
PREFIX = /var/ossec

do-install:
        mkdir -p ${PREFIX}/bin
        mkdir -p ${PREFIX}/logs
        mkdir -p ${PREFIX}/var/run
        mkdir -p ${PREFIX}/queue
        mkdir -p ${PREFIX}/active-response/bin
        mkdir -p ${PREFIX}/agentless
        mkdir -p ${PREFIX}/etc/orig/shared
        mkdir -p ${PREFIX}/doc
        ${INSTALL_SCRIPT} ${WRKSRC}/active-response/firewalls/pf.sh ${PREFIX}/active-response/bin/
        ${INSTALL_SCRIPT} ${WRKSRC}/src/agentlessd/scripts/* ${PREFIX}/agentless
        ${INSTALL_SCRIPT} ${WRKSRC}/src/os_execd/ossec-execd ${PREFIX}/bin/
        ${INSTALL_SCRIPT} ${WRKSRC}/src/logcollector/ossec-logcollector ${PREFIX}/bin/
        ${INSTALL_SCRIPT} ${WRKSRC}/src/client-agent/ossec-agentd ${PREFIX}/bin/
        ${INSTALL_SCRIPT} ${WRKSRC}/src/addagent/manage_agents ${PREFIX}/bin/
        ${INSTALL_SCRIPT} ${WRKSRC}/src/syscheckd/ossec-syscheckd ${PREFIX}/bin/
        ${INSTALL_SCRIPT} ${WRKSRC}/src/os_auth/agent-auth ${PREFIX}/bin/
        ${INSTALL_SCRIPT} ${WRKSRC}/src/init/ossec-client.sh ${PREFIX}/bin/
        ${INSTALL_SCRIPT} ${WRKSRC}/doc/*.txt ${PREFIX}/doc/
        ${INSTALL_SCRIPT} ${WRKSRC}/doc/README.config ${PREFIX}/doc/
        ${INSTALL_SCRIPT} ${WRKSRC}/etc/*.conf ${PREFIX}/etc/orig/
        ${INSTALL_SCRIPT} ${WRKSRC}/etc/*.xml ${PREFIX}/etc/orig/
        ${INSTALL_SCRIPT} ${WRKSRC}/src/rootcheck/db/* ${PREFIX}/etc/orig/shared/

.include &amp;lt;bsd.port.mk&amp;gt;;
</pre>



<p>The above Makefile will install OSSEC in<em> /var/ossec</em> and will only install the agent files. It does not install the server files.</p>



<h2 class="wp-block-heading">Step 4: Test the settings</h2>



<p>First we will make a checksum and then we will start a fake compile run, to see if everything compiles nicely.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">make makesum 
===&amp;gt;  Checking files for ossec-hids-2.8.2
`/usr/ports/distfiles/ossec-hids-2.8.2.tar.gz' is up to date.

make fake
===&amp;gt;  Checking files for ossec-hids-2.8.2
`/usr/ports/distfiles/ossec-hids-2.8.2.tar.gz' is up to date.
&amp;gt;&amp;gt; (SHA256) ossec-hids-2.8.2.tar.gz: OK
===&amp;gt;  Extracting for ossec-hids-2.8.2
===&amp;gt;  Patching for ossec-hids-2.8.2
===&amp;gt;  Configuring for ossec-hids-2.8.2
===&amp;gt;  Building for ossec-hids-2.8.2
***snip***</pre>



<p>If there were no errors, then we are ready to create the actual package.</p>



<h2 class="wp-block-heading">Step 5: Create the OpenBSD package</h2>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">mkdir pkg
echo "OSSEC is an Open Source HIDS" &amp;amp;gt; pkg/DESCR
make plist
vim pkg/PLIST
</pre>



<p>Normally we do not need to edit the PLIST file, but I wanted to create an ossec user upon installation and chown the <em>/var/ossec</em> directory to that user.<br />So I have added the following lines to the top of <em>pkg/PLIST</em>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@comment $OpenBSD$
@newgroup ossec:1002
@newuser ossec:1005:ossec:daemon:OSSEC User:/var/ossec:/bin/sh</pre>



<p>And these to the bottom:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@exec-add mkdir -p /var/ossec
@exec-add chown -R ossec.ossec /var/ossec
@exec-add cp %D/bin/ossec-client.sh /etc/rc.d/ossec</pre>



<p>Afterwards you will need to run:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">make plist</pre>



<p>Now we are ready to build the package:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">make package
`/usr/ports/pobj/ossec-hids-2.8.2/fake-amd64/.fake_done' is up to date.
===&amp;gt;  Building package for ossec-hids-2.8.2
Create /usr/ports/packages/amd64/no-arch/ossec-hids-2.8.2.tgz
Link to /usr/ports/packages/amd64/all/ossec-hids-2.8.2.tgz
Link to /usr/ports/packages/amd64/ftp/ossec-hids-2.8.2.tgz
Link to /usr/ports/packages/amd64/cdrom/ossec-hids-2.8.2.tgz</pre>



<p>That&#8217;s it! This package can now be installed with the <code>pkg_add</code> command.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pkg_add ./ossec-hids-2.8.2.tgz 
quirks-2.114 signed on 2015-08-09T11:57:52Z
UNSIGNED PACKAGE file:./ossec-hids-2.8.2.tgz: install anyway ? [y/N/a] y
ossec-hids-2.8.2: ok
UNSIGNED PACKAGES: ossec-hids-2.8.2</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://jmorano.moretrix.com/2016/03/ossec-building-an-openbsd-package/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Perl: Archive E-Mails in an IMAP Folder</title>
		<link>https://jmorano.moretrix.com/2015/11/perl-archive-e-mails-in-an-imap-folder/</link>
					<comments>https://jmorano.moretrix.com/2015/11/perl-archive-e-mails-in-an-imap-folder/#comments</comments>
		
		<dc:creator><![CDATA[Johnny Morano]]></dc:creator>
		<pubDate>Thu, 05 Nov 2015 09:33:47 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[IMAP]]></category>
		<category><![CDATA[SysAdmin]]></category>
		<guid isPermaLink="false">http://jmorano.moretrix.com/?p=1199</guid>

					<description><![CDATA[IMAP folders are really because you can have your e-mails synchronized on multiple devices, without losing e-mails across&#8230;]]></description>
										<content:encoded><![CDATA[
<p>IMAP folders are really because you can have your e-mails synchronized on multiple devices, without losing e-mails across your devices when retrieving your new e-mails. IMAP folders actually also aren&#8217;t that cool because e-mails are usually never deleted or even archived. Having millions of e-mails can make some e-mail readers on certain devices really slow.</p>



<p>The below script is an example how to clean and archive e-mails. The script was written in Perl and tested on a Courier IMAP server. Remember the Perl devise: there are million ways to write Perl scripts.</p>



<p>The following modules were used:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use Net::IMAP::Simple::SSL;
use Email::Simple;
use Getopt::Long qw/:config bundling/;
use DateTime;
use YAML qw/LoadFile/;
use Log::Log4perl;
use Pod::Usage;
use Data::Dumper;</pre>



<p>The configuration file is written in YAML and the logging of the script is handled by Log4Perl.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">log4perl.logger.shihai= DEBUG, shihaiLogfile
log4perl.logger.hostlistdb= DEBUG, shihaiLogfile

log4perl.appender.shihaiLogfile          = Log::Log4perl::Appender::File
log4perl.appender.shihaiLogfile.filename = /var/tmp/shihai.log
log4perl.appender.shihaiLogfile.layout   = Log::Log4perl::Layout::PatternLayout
log4perl.appender.shihaiLogfile.layout.ConversionPattern = %d %p [%x][%r millis][%c][%F{1}:%L][%M] %m%n</pre>



<p>The configuration file contains the login credentials and the threshold values:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">imap:
    host: 'mail.example.com'
    user: 'bob@example.com'
    pass: 'myultrasecretpassword'

threshold:
    archive:
        years: 3
    delete:
        years: 8
</pre>



<p>The threshold values are in fact the same parameters that can be used in the DateTime method &#8216;subtract()&#8217;;</p>



<p>The main loop of the program will:</p>



<ul class="wp-block-list"><li>Connect to the IMAP server</li><li>Retrieve all IMAP folders and loop through them</li><li>Loop through all messages in each mailbox</li></ul>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># Connect to the IMAP server
my $imap = connect_imap( $config-&amp;gt;{imap} );

# get all mailboxes and loop through them
my @mailboxes = get_mailboxes($imap);
foreach my $mailbox_name (@mailboxes){

    # Skip all Archive boxes 
    next if $mailbox_name =~ /Archive/;

    # select the mailbox and get the number of messages
    my $mb = $imap-&amp;gt;select($mailbox_name);
    unless(defined $mb){
        $logger-&amp;gt;error("Mailbox [$mailbox_name] doesn't exist: ", $imap-&amp;gt;errstr());
        next;
    }

    $logger-&amp;gt;info("Scanning $mailbox_name");

    # loop through the messages
    foreach my $i (1 .. $mb){
        my ($from, $subject, $date, $year) = get_mail_header($imap, $i);

        if(defined $date){
            if($date &amp;lt; $delete_date ){
                delete_mail($imap, $i);
            }
            elsif($date &amp;lt; $archive_date){
                $logger-&amp;gt;info("Archiving [$i][$from][$subject][$date]");
                my $archive_box = get_archive_box($imap, $mailbox_name);
                move_mail($imap, $i, $archive_box)
            }
        }
    }

    $imap-&amp;gt;expunge_mailbox($mailbox_name);
}

$imap-&amp;gt;quit;
</pre>



<p>Let&#8217;s go through the different subroutines called in the mainloop.</p>



<p><strong>connect_imap()</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">sub connect_imap {
    my ($cfg) = @_;
    my $logger = Log::Log4perl-&amp;gt;get_logger('shihai.archive_mail');

    my $imap = Net::IMAP::Simple::SSL-&amp;gt;new($cfg-&amp;gt;{host})
        or $logger-&amp;gt;logdie("Unable to connect to IMAP server: $Net::IMAP::Simple::errstr");
    $logger-&amp;gt;info("Connected to IMAP host $cfg-&amp;gt;{host}");

    unless( $imap-&amp;gt;login($cfg-&amp;gt;{user}, $cfg-&amp;gt;{pass}) ){
        $logger-&amp;gt;logdie("Login failed: ", $imap-&amp;gt;errstr);

    }
    $logger-&amp;gt;info("Logged to IMAP host $cfg-&amp;gt;{host} as user '$cfg-&amp;gt;{user}'");

    return $imap;
}
</pre>



<p>The parameters expected in the &#8216;$cfg&#8217; hash are:</p>



<ul class="wp-block-list"><li>host</li><li>user</li><li>pass</li></ul>



<p><strong>get_mailboxes()</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">sub get_mailboxes {
    my ($imap) = @_;
    my @mailboxes = $imap-&amp;gt;mailboxes;
    my $logger = Log::Log4perl-&amp;gt;get_logger('shihai.archive_mail');

    return @mailboxes;
}
</pre>



<p>Ok, I admit, I shouldn&#8217;t have created an extra subroutine for it&#8230; but i was kind of in a flow!</p>



<p><strong>get_mail_header()</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">sub get_mail_header {
    my ($imap, $i) = @_;
    my $logger = Log::Log4perl-&amp;gt;get_logger('shihai.archive_mail');

    my $header = $imap-&amp;gt;top($i);
    unless( $header ){
        $logger-&amp;gt;error("No header found for message $i in ", $imap-&amp;gt;current_box);
    }
    
    my $email = Email::Simple-&amp;gt;new(join '', @{ $header });
    unless( $email ){
        $logger-&amp;gt;error("No Email::Simple object, skipping...");
        return
    }

    my ($subject) = $email-&amp;gt;header('Subject');
    my ($date)    = $email-&amp;gt;header('Date');
    my ($from)    = $email-&amp;gt;header('From');

    # $logger-&amp;gt;debug("Got e-mail [$from] [$subject] [$date]");

    unless(defined $date){
        $logger-&amp;gt;error("No date found: ", $email-&amp;gt;header_obj-&amp;gt;as_string);
        delete_mail($imap, $i);
        return;
    }
    
    my($junk, $day, $month, $year) = ( $date =~ m/(...,\s+)?([0-9]{1,2})\s+(...)\s+(\d{4})/ );

    my $date_obj;
    if(defined $year &amp;amp;&amp;amp; defined $month &amp;amp;&amp;amp; defined $day){
        $date_obj = DateTime-&amp;gt;new(
            year  =&amp;gt; $year,
            month =&amp;gt; $months{$month},
            day   =&amp;gt; $day,
        );
    }    

    return ($from, $subject, $date_obj, $year, $month, $day);
}
</pre>



<p>This subroutine takes the &#8216;$imap&#8217; object and the message number as input parameters. It will then retrieve the mail header and convert it to an &#8216;Email::Simple&#8217; object. I&#8217;ve chosen this module so I can easily extract header fields.<br />If no &#8216;Date:&#8217; field was found in the e-mail, then the tool will just delete the email. I don&#8217;t like e-mails with wrong or missing headers <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> (they&#8217;re usually spam anyway).</p>



<p><strong>delete_mail()</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">sub delete_mail {
    my($imap, $i) = @_;
    my $logger = Log::Log4perl-&amp;gt;get_logger('shihai.archive_mail');

    if( $imap-&amp;gt;delete($i) ){
        $logger-&amp;gt;info("Deleted message number $i from ", $imap-&amp;gt;current_box);
    }
}
</pre>



<p>Pretty straightforward.</p>



<p><strong>get_archive_box()</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">sub get_archive_box{
    my($imap, $mailbox_name) = @_;
    my $logger = Log::Log4perl-&amp;gt;get_logger('shihai.archive_mail');

    my ($archive_box) = ($mailbox_name);
    $archive_box =~ s/INBOX/INBOX.Archive/;

    if( not grep /^$archive_box$/, @mailboxes) {
        create_mailbox($imap, $archive_box);
        subscribe($imap, $archive_box);
    }

    return $archive_box;       
}
</pre>



<p>This subroutine will assemble the archive mailbox name. It will then check if the mailbox already exists and otherwise create it and subscribe to it.</p>



<p><strong>create_mailbox()</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">sub create_mailbox {
    my($imap, $mb) = @_;
    my $logger = Log::Log4perl-&amp;gt;get_logger('shihai.archive_mail');

    $imap-&amp;gt;create_mailbox($mb) or $logger-&amp;gt;logdie("Mailbox creation '$mb' failed: ", $imap-&amp;gt;errstr());
    $logger-&amp;gt;info("Created mailbox $mb");
}
</pre>



<p>It will basically just create the mailbox and log about it.</p>



<p><strong>subscribe()</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">sub subscribe {
    my($imap, $box) =@_;
    my $logger = Log::Log4perl-&amp;gt;get_logger('shihai.archive_mail');

    $imap-&amp;gt;folder_subscribe($box);
    $logger-&amp;gt;info("Subscribed to mailbox $box");
}
</pre>



<p><strong>move_mail()</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">sub move_mail {
    my($imap, $i, $new_box) = @_;
    my $logger = Log::Log4perl-&amp;gt;get_logger('shihai.archive_mail');

    if( $imap-&amp;gt;copy($i, $new_box) ){
        $logger-&amp;gt;info("Copied message number [$i] from ", $imap-&amp;gt;current_box ," to [$new_box]");
        delete_mail($imap, $i);
    }
}
</pre>



<p>Moving an e-mail consists of copying it first to the new mailbox and then afterwards removing it from the old mailbox.</p>



<p>And that&#8217;s basically it!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jmorano.moretrix.com/2015/11/perl-archive-e-mails-in-an-imap-folder/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
