Resizing libvirt disks. Sharing dirs from host <-> guest

1. Resize

Inside the guest system, check the current size of the disk (for example /dev/vda).

fdisk -l /dev/vda
Disk /dev/sda: 160.0 GB, 160041885696 bytes, 312581808 sectors
Units = sectors of 1 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

On the host, resize the logical volume holding the /dev/vda disk of the guest to the required size, for example 200 GB.

lvresize -L 200G /dev/mapper/vg00-home
Extending logical volume home to 200 GiB
Logical volume home successfully resized

On the host, resize the block device related to the disk /dev/mapper/vg00-home of the guest. Note that you can find the DOMAIN_ID with virsh list.

virsh blockresize --path /dev/vg00/home --size 200G DOMAIN_ID
Block device '/dev/vg00/home' is resized

Check that the new disk size is accepted by the guest.

fdisk -l /dev/vda
Disk /dev/sda: 200.0 GB, 200052357120 bytes, 390727260 sectors
Units = sectors of 1
512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

2. Share directory from host to guest

1. enable shared memory

    <source type='memfd'/>
    <access mode='shared'/>

2. Share the directory

<filesystem type='mount' accessmode='passthrough'>
      <driver type='virtiofs'/>
      <binary xattr='on'>
        <lock posix='on' flock='on'/>
      <source dir='/mnt/shared_files'/>
      <target dir='mount_shared_files'/>

3. Start/Restart the vm and mount the dir

mount_shared_files /mnt/host/   virtiofs        ro,defaults     0       0

or CLI

mount -t virtiofs mount_shared_files /mnt/host

Extending Qcow2 partition

Taken from

Let’s check what is the current size.

# qemu-img info hosta.qcow2
image: hosta.qcow2
file format: qcow2
virtual size: 30 GiB (32212254720 bytes)
disk size: 1.18 GiB
cluster_size: 65536
Format specific information:
compat: 1.1
compression type: zlib
lazy refcounts: true
refcount bits: 16
corrupt: false
Let’s add 20GiB to this disk to make it to 50GiB.

# qemu-img resize hosta.qcow2 +20G
Image resized.
Next we need to resize the filesystem on this disk. There are a few ways to do this such as attaching this hostq.qcow2 to another VM and expand it there, or just manually grow the LVM volume group in my case. However, I found a really cool way by using the virt-resize command.

# cp hosta.qcow2 hosta-orig.qcow2
Then carefully instruct the virt-resize to expand the correct partition. On my server, /dev/sda1 is used for /boot and /dev/sda2 is used as a LVM physical volume.

There is a nice trick to display the disk filesystem on a (KVM) VM.

# virt-filesystems --long -h --all -a hosta.qcow2
Name Type VFS Label MBR Size Parent
/dev/sda1 filesystem xfs - - 1014M -
/dev/cl/root filesystem xfs - - 27G -
/dev/cl/swap filesystem swap - - 2.0G -
/dev/cl/root lv - - - 27G /dev/cl
/dev/cl/swap lv - - - 2.0G /dev/cl
/dev/cl vg - - - 29G /dev/sda2
/dev/sda2 pv - - - 29G -
/dev/sda1 partition - - 83 1.0G /dev/sda
/dev/sda2 partition - - 8e 29G /dev/sda
/dev/sda device - - - 50G -
From the above output, we can see that the /dev/sda has already been expanded to 50GiB. But the /dev/sda2 is still only 29GiB (1GiB has been allocated to /dev/sda1 for the Boot partition.) So let’s expand the /dev/sda2.

# virt-resize --expand /dev/sda2 hosta-orig.qcow2 hosta.qcow2
[ 0.0] Examining hosta-orig.qcow2

Summary of changes:

/dev/sda1: This partition will be left alone.

/dev/sda2: This partition will be resized from 29.0G to 49.0G. The LVM PV
on /dev/sda2 will be expanded using the ‘pvresize’ method.

[ 3.7] Setting up initial partition table on hosta.qcow2
[ 4.8] Copying /dev/sda1
[ 6.9] Copying /dev/sda2
100% ⟦▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒⟧ 00:00
[ 30.3] Expanding /dev/sda2 using the ‘pvresize’ method

Resize operation completed with no errors. Before deleting the old disk,
carefully check that the resized disk boots and works correctly.
Let’s verify our result.

# virt-filesystems --long -h --all -a hosta.qcow2
Name Type VFS Label MBR Size Parent
/dev/sda1 filesystem xfs - - 1014M -
/dev/cl/root filesystem xfs - - 27G -
/dev/cl/swap filesystem swap - - 2.0G -
/dev/cl/root lv - - - 27G /dev/cl
/dev/cl/swap lv - - - 2.0G /dev/cl
/dev/cl vg - - - 49G /dev/sda2
/dev/sda2 pv - - - 49G -
/dev/sda1 partition - - 83 1.0G /dev/sda
/dev/sda2 partition - - 8e 49G /dev/sda
/dev/sda device - - - 50G -
On the background, virt-manager actually created a temporary VM, perform the disk expansion, virt-filesystem check and remove that VM upon completion.

systemd start x11vnc on boot

# apt-get install x11vnc
# x11vnc -storepasswd /etc/vnc.password
# vi /etc/systemd/system/x11vnc.service

Description=Start x11vnc at startup.

ExecStart=/usr/bin/x11vnc -display :0 -auth guess -rfbauth /etc/vnc.password -oa /var/log/vnc.log -xkb -forever -bg -noxdamage -repeat -shared

# systemctl enable x11vnc
# systemctl start x11vnc

Limit ssh user to only use rsync

Rsync, ssh with authorized_keys

Let's say you want to backup some data on remote server.
Easiest option is to use rsync.
On the remote server you will need account so you can login and upload the data, but it would be good to limit this account to only touch data in specific dir and nothing more - no shell, no other locations.
Easiest way is to do it with ssh keys.

0. Add the user on the remote server. Do not set password so it can't login.
1. Generate the key:
$> ssh-keygen -t ed25519 -f rsync_key
2. Copy the .pub key to the server you will be syncing to.
3. Create ~/.ssh/authorized_keys on the remote server with the user that will be holding the data.
in the authorized_keys you must place a line with allowed command + limits and the key like so:

command="rsync --server -vlogDtprCze.iLsfxC --delete . /home/john/backup",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ssh-ed25519 AAAA........

4. On the computer that you have private key and the data to backup, you can run the command:
$> rsync -e 'ssh -i rsync_key' -Cavz --delete /home/johncomp/Documents john@hostname:/home/john/backup

That's it.
User john can't execute anything else than the command specified for this key.

Debian 10 - create/add rc.local file

On the latest debian version the /etc/rc.local file is deprecated, but we can add it back using systemd for those scripts or applications that still depend on it.

Note that this is not the correct way of doing it, and you should probably create a service for your script or application, but if you don’t want to spend the time just yet to migrate everything over you can simple add the rc.local file back into Debian 10.

First we need to create a service file:

$> cat /etc/systemd/system/rc-local.service


ExecStart=/etc/rc.local start


Then we create the rc.local file again

$> cat /etc/rc.local

#!/bin/sh -e
# rc.local
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
# In order to enable or disable this script just change the execution
# bits.
# By default this script does nothing.

exit 0

Then we make rc.local executable and enable and start the new service.

#> chmod +x /etc/rc.local
#> systemctl enable rc-local
#> systemctl start rc-local
#> systemctl status rc-local

You can now add what you want back into the rc.local file, of course this is not the ‘correct’ way of doing, best would be to add a service for your scripts/programs in systemd where possible.


Override mysqld.service / mariadb.service systemd default settings

If you need to override default systemd mariadb.service / mysqld.service settings, so they stay in act and persistent between updates of the systemd you just have to make:

#> systemctl edit mariadb.service

place in file whatever sections/options you want to change and they will get set in place of the default ones.

For example:
ProtectHome = false

#> systemctll deamon-reexec
#> systemctl restart mariadb

Python: Base43 string decoding

This is a reimplementation in python from:
import copy
class Base43:
    def __init__(self):
        self.base43Chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ$*+-./:'

    """long division with an arbitrary base."""
    def divMod(self,byteArr, base, divisor, startAt):
        result = copy.copy(byteArr)#.slice();
        remainder = 0
        temp = None;
        startAt = startAt if startAt else 0;
        for i in range(startAt, len(byteArr)):
            temp = remainder * base + byteArr[i]
            result[i] = temp / divisor
            remainder = temp % divisor;
        return {
            'div': result,
            'mod': remainder,

    def byteArrGreaterThan(self,byteArr, limit):
        length = len(byteArr)
        last = byteArr[length - 1]
        if last >= limit:
            return True
            for i in range(0, (length-1)):
                if byteArr[i] > 0:
                    return True
        return False;
   #input is a base-43 string, output is a hex string
    def decode(self,input):
        result = []
        input43 = []
        for i in range(0,len(input)): input43.append(i+100)

        for l in input:
            index = self.base43Chars.find(l)
            if (index < 0):
                raise Exception("Illegal character. Allowed characters are:" + self.base43Chars)
            #print "D: "+str(i)+' -> '+l+" -> "+str(index)
            input43[i] = index
            i += 1

        zeroCount = 0;
        pad = '';
        while zeroCount < len(input) and input43[zeroCount] == 0:
            zeroCount += 1;
            pad += '0';

        startAt = zeroCount

        while self.byteArrGreaterThan(input43, 256):
            r = self.divMod(input43, 43, 256, startAt);
            input43 = r['div'];


        r1 = ''
        ret = ''
        for r in result:
            if len(r1)<2:
                ret += "0"+r1
                ret += r1

        return pad + ret

Samba: working with ldap

Install samba and nss-ldap:

apt install samba libnss-ldap nscd

Configure the libnss so users/groups from ldap can be visible in unix.
During installations you will be asked question on the libnss-ldap setup.
I use ldap+tls. Here's my final /etc/libnss-ldap.conf (I have removed all commented options):
You also need to setup secret file as described in the admin line.

# The distinguished name of the search base.
base dc=example,dc=com

# Another way to specify your LDAP server is to provide an
uri ldap://
ldap_version 3

# The distinguished name to bind to the server with
# if the effective user ID is root. Password is
# stored in /etc/libnss-ldap.secret (mode 600)
# Use 'echo -n "mypassword" > /etc/libnss-ldap.secret' instead
# of an editor to create the file.
rootbinddn cn=admin,dc=example,dc=com

# Search timelimit in seconds (0 for indefinite; default 0)
timelimit 10
# Bind/connect timelimit (0 for indefinite; default 30)
bind_timelimit 30

# OpenLDAP SSL mechanism
# start_tls mechanism uses the normal LDAP port, LDAPS typically 636
ssl start_tls

# OpenLDAP SSL options
# Require and verify server certificate (yes/no)
# Default is to use libldap's default behavior, which can be configured in
# /etc/openldap/ldap.conf using the TLS_REQCERT setting. The default for
# OpenLDAP 2.0 and earlier is "no", for 2.1 and later is "yes".
tls_checkpeer yes

# CA certificates for server certificate verification
# At least one of these are required if tls_checkpeer is "yes"
tls_cacertfile /etc/ssl/certs/
tls_cacertdir /etc/ssl/certs

Then you setup your /etc/nsswitch.conf

passwd: files ldap
group: files ldap

Add users/groups in ldap and test if you see them:

#> getent passwd

#> getent group

After that you can start the caching daemon nscd so ldap don't get overloaded by queries.

#>systemctl start nscd

After that you can setup your samba to work with ldap:

# LDAP Settings
passdb backend = ldapsam:ldap://
ldap suffix = dc=example,dc=com
ldap user suffix = ou=People
ldap group suffix = ou=Groups
ldap machine suffix = ou=Computers
ldap idmap suffix = ou=Idmap
ldap admin dn = cn=admin,dc=example,dc=com
# or off if TLS/SSL is not configured
ldap ssl = start tls
ldap passwd sync = yes

I've used LDAP Account Manager to manage my ldap.

Samba: audit files activity + log in separate file

in /etc/rsyslog.d/50-smbd_audit.conf tell rsyslogd to direct audit logs to a separate file:

if $programname == 'smbd_audit' then /var/log/samba/audit.log
if $programname == 'smbd_audit' then ~

in /etc/samba/smb.conf tell samba to audit file operations:

vfs object = full_audit
full_audit:prefix = %S|%u|%I|%m
full_audit:success = chdir mkdir open opendir read rename rmdir write link unlink
full_audit:failure = none
full_audit:facility = local7
full_audit:priority = notice

and finally tell logrotate to archive the files daily – /etc/logrotate.d/smbd_audit

rotate 7
invoke-rc.d rsyslog rotate > /dev/null

then just restart both samba and rsyslog and enjoy the logs:

#> service smbd restart
#> service rsyslogd restart
#> tail -f /var/log/samba/audit.log

Installing Virtual Machines with virt-install, plus copy pastable distro

Copied from:

virt-install is a command line tool for creating new KVM , Xen or Linux container guests using the libvirt hypervisor management library. It allows you to create a VM and start an installation from the command line.

This article is a quick introduction to virt-install. It also has a copy pastable getting started examples for different distro's. Make sure to change the mirror to one near you for faster downloads.

I myself use virt-install together with kickstart, debootstrap and a PXE server to create images for Openstack. I've used in the past with a Django web frontend were developers could request and destroy vm's themself. Every requested VM was a new fresh installed one, backed by KVM and virt-install.

Please do note that you need to have kvm and libvirt running on your machine. This article does not cover the installation of those, but your package manager probably does.

Disk images
A VM needs a place to store it's data. The hypervisor emulates a disk and most of the time uses an image as its source. We can create an empty, 8 GB raw disk image with the following command:

fallocate -l 8G name.img
The KVM hypervisor supports qcow2. qcow2 images support compression, snapshots and a few other nice things like growing on demand (thin provisioning, sparse file) and a read only base image. There was a performance overhead but nowdays that is almost negligent. To create an 8 GB qcow2 image:

qemu-img create -f qcow2 ./name.qcow2 8G
The virsh-install command is an easy way to spin up a VM from the command line. It allows you to start up an installation from a remote repo (network install), from a pxe boot or from a local iso. It also allows you to just boot a vm from a (live) cd iso.

Here are some copy pastable virt-install commands to get you up and running with a few distributions. You do need to have libvirt and KVM running and the disk image should exist.

Please make sure you've created a disk image before executing these commands.

If your default bridge interface is not named br0, change that. vmbr0 is also a common one.

The VM's get 1 CPU core, 1 GB of RAM and an 8 GB disk. If you want more, change the command line accordingly.

UBUNTU 22.04 Server from ISO:
Download the iso. Mount it in /mnt

#> virt-install --name course-progress --ram 2048 --disk path=/home/vms/course-progress-disk.qcow2,size=50 --disk path=/home/vms/course-progress-swap.qcow2,size=10 --vcpus 2 --os-type linux --os-variant generic --network bridge=br1 --extra-args 'console=ttyS0,115200n8 serial' --console pty,target_type=serial --install kernel=casper/vmlinuz,initrd=casper/initrd,kernel_args="console=ttyS0"

Debian 11 WITH DISK options in vg

virt-install --name vmt01 --ram 2048 --path=/dev/vg0/vm-hdd,bus=virtio,sparse=false,cahce=none,io=native --vcpus 2 --os-type linux --os-variant generic --network bridge=br0 --graphics none --console pty,target_type=serial --location '' --extra-args 'console=ttyS0,115200n8 serial'

Debian 11
virt-install \
--name debian11 \
--ram 1024 \
--disk path=./debian11.qcow2,size=8 \
--vcpus 1 \
--os-type linux \
--os-variant generic \
--network bridge=virbr0 \
--graphics none \
--console pty,target_type=serial \
--location '' \
--extra-args 'console=ttyS0,115200n8 serial'

Debian 8
virt-install \
--name debian8 \
--ram 1024 \
--disk path=./debian8.qcow2,size=8 \
--vcpus 1 \
--os-type linux \
--os-variant generic \
--network bridge=virbr0 \
--graphics none \
--console pty,target_type=serial \
--location '' \
--extra-args 'console=ttyS0,115200n8 serial'
Debian 7
virt-install \
--name debian7 \
--ram 1024 \
--disk path=./debian7.qcow2,size=8 \
--vcpus 1 \
--os-type linux \
--os-variant debian7 \
--network bridge=virbr0 \
--graphics none \
--console pty,target_type=serial \
--location '' \
--extra-args 'console=ttyS0,115200n8 serial'
Debian 6
virt-install \
--name debian6 \
--ram 1024 \
--disk path=./debian6.qcow2,size=8 \
--vcpus 1 \
--os-type linux \
--os-variant debian6 \
--network bridge=virbr0 \
--graphics none \
--console pty,target_type=serial \
--location '' \
--extra-args 'console=ttyS0,115200n8 serial'
CentOS 7
virt-install \
--name centos7 \
--ram 1024 \
--disk path=./centos7.qcow2,size=8 \
--vcpus 1 \
--os-type linux \
--os-variant centos7 \
--network bridge=virbr0 \
--graphics none \
--console pty,target_type=serial \
--location '' \
--extra-args 'console=ttyS0,115200n8 serial'
CentOS 6
virt-install \
--name centos6 \
--ram 1024 \
--disk path=./centos6.qcow2,size=8 \
--vcpus 1 \
--os-type linux \
--os-variant centos6 \
--network bridge=virbr0 \
--graphics none \
--console pty,target_type=serial \
--location '' \
--extra-args 'console=ttyS0,115200n8 serial'
CentOS 5
virt-install \
--name centos5 \
--ram 1024 \
--disk path=./centos5.qcow2,size=8 \
--vcpus 1 \
--os-type linux \
--os-variant centos5 \
--network bridge=virbr0 \
--graphics none \
--console pty,target_type=serial \
--location '' \
--extra-args 'console=ttyS0,115200n8 serial'
Ubuntu 14.04
virt-install \
--name ubuntu1404 \
--ram 1024 \
--disk path=./ubuntu1404.qcow2,size=8 \
--vcpus 1 \
--os-type linux \
--os-variant generic \
--network bridge=virbr0 \
--graphics none \
--console pty,target_type=serial \
--location '' \
--extra-args 'console=ttyS0,115200n8 serial'
Ubuntu 12.04
virt-install \
--name ubuntu1204 \
--ram 1024 \
--disk path=./ubuntu1204.qcow2,size=8 \
--vcpus 1 \
--os-type linux \
--os-variant ubuntu12.04 \
--network bridge=virbr0 \
--graphics none \
--console pty,target_type=serial \
--location '' \
--extra-args 'console=ttyS0,115200n8 serial'
Ubuntu 10.04
virt-install \
--name ubuntu1004 \
--ram 1024 \
--disk path=./ubuntu1004.qcow2,size=8 \
--vcpus 1 \
--os-type linux \
--os-variant ubuntu10.04 \
--network bridge=virbr0 \
--graphics none \
--console pty,target_type=serial \
--location '' \
--extra-args 'console=ttyS0,115200n8 serial'
OpenSUSE 13
virt-install \
--name opensuse13 \
--ram 1024 \
--disk path=./opensuse13.qcow2,size=8 \
--vcpus 1 \
--os-type linux \
--os-variant generic \
--network bridge=virbr0 \
--graphics none \
--console pty,target_type=serial \
--location '' \
--extra-args 'console=ttyS0,115200n8 serial'
OpenSUSE 12
virt-install \
--name opensuse12 \
--ram 1024 \
--disk path=./opensuse12.qcow2,size=8 \
--vcpus 1 \
--os-type linux \
--os-variant generic \
--network bridge=virbr0 \
--graphics none \
--console pty,target_type=serial \
--location '' \
--extra-args 'console=ttyS0,115200n8 serial'
OpenSUSE 11
virt-install \
--name opensuse11 \
--ram 1024 \
--disk path=./opensuse11.qcow2,size=8 \
--vcpus 1 \
--os-type linux \
--os-variant generic \
--network bridge=virbr0 \
--graphics none \
--console pty,target_type=serial \
--location '' \
--extra-args 'console=ttyS0,115200n8 serial'
Generic ISO
Download an ISO file and give the filename to the --cdrom= parameter. This is used instead of --location. A VNC console is available on localhost, port 5999 for you to use.

An example for FreeBSD 10. First download the ISO:

Then start virt-install:

virt-install \
--name freebsd10 \
--ram 1024 \
--disk path=./freebsd10.qcow2,size=8 \
--vcpus 1 \
--os-type generic \
--os-variant generic \
--network bridge=virbr0 \
--graphics vnc,port=5999 \
--console pty,target_type=serial \
--cdrom ./FreeBSD-10.1-RELEASE-amd64-dvd1.iso \
You need to start up a VNC client to do the installation.

Do note that this method works for Windows ISO's as well.

You can get a list of supported operating system variants with the osinfo-query os command. Below you'll find an example output:

osinfo-query os
Short ID | Name | Version | ID
debian7 | Debian Wheezy | 7 |
freebsd10.0 | FreeBSD 10.0 | 10.0 |
openbsd5.5 | OpenBSD 5.5 | 5.5 |
rhel6.5 | Red Hat Enterprise Linux 6.5 | 6.5 |
rhel7.0 | Red Hat Enterprise Linux 7.0 | 7.0 |
ubuntu12.04 | Ubuntu Precise Pangolin LTS | 12.04 |
win3.1 | Microsoft Windows 3.1 | 3.1 |
win7 | Microsoft Windows 7 | 6.1 |
winxp | Microsoft Windows XP | 5.1 |
Kickstart and debootstrap
If you have a kickstart file set up you can give it directly to the vm using the --extra-args parameter:

--extra-args "ks=http://server/vm.ks"
If you don't have a server set up you can inject a file into the initrd and use that for kickstarting:

--initrd-inject=vm.ks --extra-args "ks=file:/vm.ks"
preseed.cfg is a regular preseed file (as described in the Debian Wiki) in your local filesystem. It must be named preseed.cfg in order for d-i to pick it up from the initrd.

Here is another, rather boring, image of a Debian install via virt-install:


Starting a VM
To start a VM you've just created after the installation, use the virsh start NAME command:

virsh start centos7
Use the virsh list --all to list all available virtual machines, including powered off ones:

$ virsh list --all
Id Name State
4 centos7 running
- debian7 shut off
- win7 shut off
- win98 shut off
- winxp shut off
Stopping and removing
To stop a VM, you give the (unintuitive) command virsh destroy NAME:

virsh destroy centos7
It will not remove any data, just stop the VM by pulling the virtual power cable.

If you want to remove the VM from the virsh list, you need to undefine it:

virsh undefine centos7
This will remove the configuration. If you don't undefine the VM and want to try the virt-install again it will give an error like this:

ERROR Guest name 'centos7' is already in use.
You do manually need to remove the virtual disk after undefining a vm.

Debugging Angular 4 from Chrome console

Right click and inspect the element(component) you want to debug.

Then you can go to console and access the component variable by


When you want to detect UI changes



Dovecot custom certificate per each ip

You can add:

local {
ssl_cert = </etc/ssl/domains/
ssl_key = </etc/ssl/domains/
ssl_ca = </etc/ssl/domains/

in your 10-ssl.conf so you can have different cert despite the default one.

Postfix: force outgoing mail for specified domain trough separate ip

To be able to send each domain mail from different ip you have to do the following:

#> vi /etc/postfix/
add postfix listener bound on alternative ip in after smtp line: transport
domaincom_transport unix - - y - - smtp
-o smtp_bind_address=$domaincom_transport_bind_address
-o syslog_name=smtp-domain

#> vi /etc/postfix/
domaincom_transport_bind_address =
#mask outgoing mails on a per domain to ip match base - add a line
sender_dependent_default_transport_maps = hash:/etc/postfix/sender_transport

then create the file for mapping

#> vi /etc/postfix/sender_transport domaincom domain2 domain3

save and exit and create hash db:
#> postmap hash:/etc/postfix/sender_transport

/etc/init.d/postfix restart

Rewrite From header in postfix

The essential steps
Create /etc/postfix/header_checks (discussed below) then run these commands
cd /etc/postfix
postconf -e 'smtp_header_checks = regexp:/etc/postfix/header_checks'
/etc/init.d/postfix reload
Developing the header_checks file
Line format
For present purposes, each effective line of the header_checks file is of the form
/pattern/ REPLACE text...
The pattern
The /pattern/ is a POSIX regular expression matching the "FROM:" header. So it always begins with
The pattern should always be anchored to the start of the line using ^. This ensures no false positives (such as matching "From:" in some other header such as the subject) and gives better postfix performance (postfix does not have to scan the whole of each header looking for the match).
The rest of the pattern depends on local requirements – what you want to match.
Any whitespace in the pattern should be represented by [[:space:]]. This avoids warnings from postmap such as "record is in "key: value" format; is this an alias file?" and "duplicate entry".
The text
display-name needs double quotes.
angle-addr needs the < and > characters.
Development techniques
To find out what's after the "From:":
If the regex matches, the original headers can be displayed by
grep -o 'replace: header .*$' /var/log/
Keep the original header text in the re-written header by using back-substitution in header_checks like (replace ):
/^From:[[:space:]]+(.*)/ REPLACE From: ">${1}<"

Postfix Architecture Overview:
Postfix Address Rewriting:
Postfix Lookup Table Overview:
REGEXP_TABLE man page:
header_checks man page:

Extend LVM partition with XFS

1. Check free space:
#> vgs vgname

2. Extend vg (-r is for auto extend fs):

#> lvextend -r -L +3G /dev/vgname/xfs_part

3.1. Extend xfs
#> xfs_growfs -D

3.2. Extend ext4
#> resize2fs

The “-D size” option extend the file system to the specified size (expressed in file system blocks). Without the -D size option, xfs_growfs will extend the file system to the maximum size supported by the device.

Debian Auto update / Unattended update

Here's a quick way, to enable Debian to autoupdate.
1. Install unattended upgrades and mailx.
#> apt-get install unattended-upgrades bsd-mailx
2. Configure the upgrades
#> vi /etc/apt/apt.conf.d/50unattended-upgrades

Normally the default configuration should be ok; if you want to change anything, please read the comments in the file which make the configuration self-explaining. For example, you can specify the upgrade origins (default: stable and security), you can blacklist packages that should not be updated, you can have the system email you if there are problems, you can have the system remove unused dependencies after an update, or you can make the system do an automatic reboot if this is needed after an update. Please note: The double slashes // serve as a comment; anything that follows a comment in the same line will not be evaluated.

3. Then create file /etc/apt/apt.conf.d/02periodic to enable it.

// Enable the update/upgrade script (0=disable)
APT::Periodic::Enable "1";

// Do "apt-get update" automatically every n-days (0=disable)
APT::Periodic::Update-Package-Lists "1";

// Do "apt-get upgrade --download-only" every n-days (0=disable)
APT::Periodic::Download-Upgradeable-Packages "1";

// Run the "unattended-upgrade" security upgrade script
// every n-days (0=disabled)
// Requires the package "unattended-upgrades" and will write
// a log in /var/log/unattended-upgrades
APT::Periodic::Unattended-Upgrade "1";

// Do "apt-get autoclean" every n-days (0=disable)
APT::Periodic::AutocleanInterval "7";

Unattended upgrades will run once per day from the cron /etc/cron.daily/apt
The script will log to the file /var/log/unattended-upgrades/unattended-upgrades.log

Clone/Replace HDD in Software RAID

When replacing hdd in software raid, easiest way to do it is to clone partition table from the healthy disk on the new one. Regenerate UUIDS and add new disk in the array.

Here's how we do it. (/dev/sda is healthy disk)

For MBR Disks:

# sfdisk -d /dev/sda | sfdisk /dev/sdb

also can do a partitions rescan:
# sfdisk -R /dev/sdb

For GPT Disks:
WARNING: /dev/sdb is the DESTINATION! /dev/sda is SOURCE.

# sgdisk -R /dev/sdb /dev/sda

then set new UUIDs

# sgdisk -G /dev/sdb

then check if partitions have appeared:

# fdisk -l /dev/sdb

after that simply add your partitions:

# mdadm /dev/md0 -a /dev/sdb1
....add all md dev-disk pair...

then you can watch it syncing:

# watch cat /proc/mdstat

afterwards don't forget to install grub:

# grub-install /dev/sdb

Postfix - relay trough other smtp server with email authorization

To relay our mail from a home/office server trough real mail server, that has all needed stuff like PTR, SPF, DKIM etc. stuff setup, the easies way is to 'login' to a free, open service like gmail, yahoo etc. server and send from our account there.
So, let's do this with postfix.
The EASY way to do is, if the provider supports submission protocol (port 587).
Then in we set a relayhost

relayhost = []:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_CAfile = /etc/postfix/cacert.pem
smtp_use_tls = yes

then we create /etc/postfix/sasl_passwd:


we create hash file:
#> postmap /etc/postfix/sasl_passwd

then we make:
#> chmod 400 /etc/postfix/sasl_passwd*
and then
#> /etc/init.d/postfix restart
#> systemctl restart postfix (8 and above)

The HARD way is to do it with stunnel program.
We should do this ONLY if provider supports only ssl smtp connection.

Make sure stunnel is installed:
#> apt-get install stunnel4

First, make same steps as above BUT relayhost is with other valie:
then in /etc/postfix/ check

relayhost =

After setting relay to localhost at random port, we setup stunnel.
We create /etc/stunnel/
It holds this:

client = yes
chroot = /var/lib/stunnel4/
setuid = stunnel4
setgid = stunnel4
pid = /
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1

accept =
connect =

Then, we restart stunnel and postfix and we are ready.

Remove failed disk from LVM group

Removing a Disk from a Logical Volume
Moving Extents to Existing Physical Volumes
#> pvs -o+pv_used

We want to move the extents off of /dev/md4 so that we can remove it from the volume group.
If there are enough free extents on the other physical volumes in the volume group, you can execute the pvmove command on the device you want to remove with no other options and the extents will be distributed to the other devices.
#> pvmove /dev/md4

After the pvmove command has finished executing, check the distribution of extents :
#> pvs -o+pv_used

Use the vgreduce command to remove the physical volume /dev/md4 from the volume group.
# vgreduce vg_name /dev/md4
Removed "/dev/md4" from volume group "vg_name"
# pvs

Debian systemd run process at startup

This is a copy of: (because it disappeared).

Run Script at Start on Debian/Ubuntu

July 3, 2013

Updated: Dec 12, 2015

Determine Init System

Newer installs use systemd as the init system, which has a newer and more
consisten way to manage services. There was a lot of linux drama around this
change, my guess mostly due to "cheese moving" and having to learn something

You can determine if your system is running systemd using: $ ps -p1

Start Daemon on System boot

The main reason I need this script is becaues BitTorrent Sync is not distributed as an Ubuntu package with necessary start scripts. Also, btsync needs to run as the user, which I often forget. First create the service file which describes how to start and information about the service.

Saved to: /etc/systemd/user/btsync.service

Description=BitTorrent Sync Service

ExecStart=/home/mkaz/bin/btsync --config /home/mkaz/.btsync.conf



sudo systemctl enable /etc/systemd/user/btsync.service


sudo systemctl start btsync.service

That's it, it should be running now and each time you start. You can test by rebooting and confirming it works. The above is not ideal for multi-user servers, since I'm hardcoding everything to my user, adjust to your needs.


There is a lot more information available around systemd and a lot more
configuration available for example to execute a command before start, or other

systemd throttling too fast - debian jessie bug

Systemd looks nice, but makes a lot more trouble than it helps (according to me).
There is a nasty bug in current jessie systemd 215 which makes it from time to time to say:
systemd[1]: Looping too fast. Throttling execution a little.
and eats up cpu.

The only way I've found, to solve temporary, without reboot is

#> systemctl daemon-reexec

Sniffing Unix Socket - debugging communication between nginx and php-fpm

Ever wondered how to sniff communication of a unix socket?
Here's how:

#> socat -t100 -x -v UNIX-LISTEN:/var/run/php5-fpm.sock.socat,mode=777,reuseaddr,fork UNIX-CONNECT:/var/run/php5-fpm.sock

You can remove -x and just leave -v for ascii communication.
Hope that helps someone.

xl block-attach - cool!

Just wanted to copy something from usb flash drive inside my vm.
Wondered what's the fastest and easiest way to do it and viola:

#> xl block-attach 10 phy:/dev/sdb1 xvdf1 w

then, inside vm mount /dev/xvdf1

afterwards detach it (after freeing resources):

># xl block-detach 10 xvdf1

The interesting thing is that the I got about 20MB/s speed from the usb (it is usually that fast - 3.0 usb drive, plugged in 2.0 port).

Starting x11vnc from init.d in jessie

I've spent last hour trying to make a descent init.d script 'new way' that's working properly so I can have x11vnc started at boot time.
Here it is:
# Provides:          x11vnc
# Should-Start:
# Required-Start:    gdm3
# Required-Stop:
# Default-Start:     5
# Default-Stop:      0 1 2 6
# Short-Description: x11vnc server
# Description:       Debian init script for the x11vnc server
# Author:       Anton Valqkoff < anton  valqk  com >
set -e
SERVICE=$(basename $0)
OPT=" -display :0 -auth guess -rfbauth /etc/x11vncpassword -oa /var/log/vnc.log -xkb -forever"

test -x $BIN || exit 0

if [ -r /etc/default/locale ]; then
  . /etc/default/locale

. /lib/lsb/init-functions

case "$1" in
        CONFIGURED_DAEMON=$(basename "$(cat $DEFAULT_DISPLAY_MANAGER_FILE 2> /dev/null)")
        if [ `ps ax|grep $SERVICE|grep -v grep|wc -l` -gt 1 ]; then
                log_daemon_msg "Starting $SERVICE server" "$SERVICE"
        set +e
                start-stop-daemon --start --pidfile $PIDFILE -m --background --exec $BIN -- $OPT || log_end_msg 1
                log_end_msg 0
        set -e
            log_daemon_msg "$SERVICE Already started..." "$SERVICE"
        log_daemon_msg "Stopping $SERVICE" "$SERVICE"
        set +e
        start-stop-daemon --stop --quiet --pidfile $PIDFILE \
                --name $SERVICE --retry 5
        set -e
        log_end_msg $?
        log_daemon_msg "Scheduling reload of $SERVICE" "$SERVICE"
        set +e
        start-stop-daemon --stop --signal HUP --quiet --pidfile $PIDFILE \
                --name $SERVICE
        set -e
        log_end_msg $?
        status_of_proc -p "$PIDFILE" "$BIN" $SERVICE && exit 0 || exit $?
        $0 stop
        $0 start
        echo "Usage: $0 {start|stop|restart|reload|force-reload|status}"
        exit 1

exit 0

Bash loop delimiter



at your bash prompt will set the delimiter a for loop uses to a newline.

You can do:


for i in `cat $somefile`;
echo $i;

List of all Symfony2 Exceptions (symfony)

Source: http:\\\list-of-all-symfony2-exceptions-symfony.html

I regularly want a list of all the symfony2 exceptions to see if there are any that I can reuse, instead of creating my own.
Unfortunately, I have found no way to find a list of all the exceptions, so I took it upon myself to create an Exception list.
The list below shows all the exceptions with their full namespace as of Symfony 2.1.2


Since most symfony2 installations also include doctrine2, below is a list of all the Doctrine 2 Exceptions.


Xen Block Devices Usage tap2:aio

In case of getting max loop devices reached and have already built image of VM and you CAN't restart machine to increase max_loop=XX when loading loop module,
use tap:aio.

#> apt-get install blktap-dkms blktap-utils
#> modprobe blktap

Then change the config of vm from file:/ to tap2:tapdisk:aio:/
Something like this:

bootloader = '/usr/lib/xen-4.1/bin/pygrub'
vcpus = '1'
memory = '512'
root = '/dev/xvda2 ro'
disk = [
name = ''
vif = [ 'ip= ,mac=01:06:1A:12:FE:C5' ]
on_poweroff = 'destroy'
on_reboot = 'restart'
on_crash = 'restart'

Screencast with ffmpeg


Some Useful FFMPEG Commands (Screencasting, Rotate Video, Add Logo, etc.)

In this tutorial we will see some useful FFMPEG commands that you can use on Ubuntu/Linux Mint to make screencasting videos, rotate videos, add logo/text watermarks to a video, insert shapes, and so on.

To install ffmpeg and some other packages on Ubuntu/Linux Mint, open the terminal and run these commands:

sudo apt-get install ubuntu-restricted-extras

sudo apt-get install ffmpeg x264

sudo apt-get install frei0r-plugins mjpegtools

Note: The file formats used in this tutorial are selected randomly and you can set any other extension of your choice.

1. Screecasting

To record your screen withh FFMPEG, you can use this command:

ffmpeg -f x11grab -follow_mouse 100 -r 25 -s vga -i :0.0 filename.avi

Now the command will record every spot on your screen you hover your mouse cursor over. Press Ctrl+C to stop recording. If you want to set a screen resolution for the video to be recorded, you can use this ffmpeg command:

ffmpeg -f x11grab -s 800x600 -r 25 -i :0.0 -qscale 5 filename.avi

To show the region that will be recorded while moving your mouse pointer, use this command:

ffmpeg -f x11grab -follow_mouse centered -show_region 1 -r 25 -s vga -i :0.0 filename.avi

If you want to record in fullscreen with better video quality (HD), you can use this command:

ffmpeg -f x11grab -s wxga -r 25 -i :0.0 -sameq video.mp4

Her is a video example created with the latter command:

2. Add Audio To A Static Picture

If you want to add music to a static picture with ffmpeg, run this command from the terminal:

ffmpeg -i audio.mp3 -loop_input -f image2 -i file.jpg -t 188 output.mp4

3. Add Image Watermarks to A Video

To add an image to a video using ffmpeg, you can use one of these commands:

Picture Location: Top Left Corner

ffmpeg -i input.avi -vf "movie=file.png [watermark]; [in][watermark] overlay=10:10 [out]" output.flv

Here is an example:

Picture Location: Top Right Corner

ffmpeg –i input.avi -vf "movie=watermarklogo.png [watermark]; [in][watermark] overlay=main_w-overlay_w-10:10 [out]" output.flv

Picture Location: Bottom Left Corner

ffmpeg –i input.avi -vf "movie=watermarklogo.png [watermark]; [in][watermark] overlay=10:main_h-overlay_h-10 [out]" output.flv

Picture Location: Bottom Right Corner

ffmpeg –i input.avi -vf "movie=watermarklogo.png [watermark]; [in][watermark] overlay=main_w-overlay_w-10:main_h-overlay_h-10 [out]" output.flv

4. Add Text Watermarks To Videos

To add text to a video, use this command:

ffmpeg -i input.mp4 -vf drawtext="fontfile=/usr/share/fonts/truetype/freefont/FreeSans.ttf: text='YOUR TEXT HERE':fontcolor=red@1.0:fontsize=70:x=00: y=40" -y output.mp4

An example:

To use another text font, you can list them from the terminal with this command:

ls /usr/share/fonts/truetype/freefont/

4. Rotate Videos

To rotate a video 90 degrees with ffmpeg, run this command:

ffmpeg -i input.avi -vf transpose=1 output.avi

Here is an example for a video rotated with ffmpeg:

Here is all parameters:

0 = 90 degrees CounterCLockwise (Vertical Flip (default))
1 = 90 degrees Clockwise
2 = 90 degrees CounterClockwise
3 = 90 degrees Clockwise (Vertical Flip)

5. Adjust Audio/Video Volume
You can use ffmpeg to change volume of a video file with this command:

ffmpeg -i input.avi -vol 100 output.avi

To change volume of an audio file, run this command:

ffmpeg -i input.mp3 -vol 100 -ab 128 output.mp3

6. Insert A Video Inside Another Video

To do this, run this command:

ffmpeg -i video1.mp4 -vf "movie=video2.mp4:seek_point=5, scale=200:-1, setpts=PTS-STARTPTS [movie]; [in] setpts=PTS-STARTPTS, [movie] overlay=270:240 [out]" output.mp4

Here is an example:

7. Add a Rectangle To A Video

To draw for example an orange rectangle in a video, you can use this command:

ffmpeg -i input.avi -vf "drawbox=500:150:600:400:orange@0.9" -sameq -y output.avi

How to create and start VirtualBox VM without GUI


Suppose you want to create and run virtual machines (VMs) on VirtualBox. However, a host machine does not support X11 environment, or you only have access to a terminal on a remote host machine. Then how can you create and run VMs on such a host machine without VirtualBox GUI? This can be a common situation for servers where VMs are managed from remotely.

In fact, VirtualBox comes with a suite of command line utilities, and you can use the VirtualBox command line interfaces (CLIs) to manage VMs on a remote headless server. In this tutorial, I will show you how to create and start a VM without VirtualBox GUI.

Prerequisite for starting VirtualBox VM without GUI

First, you need to install VirtualBox Extension Pack. The Extension Pack is needed to run a VRDE remote desktop server used to access headless VMs. Its binary is available for free. To download and install VirtualBox Extension Pack:

$ wget
$ sudo VBoxManage extpack install ./Oracle_VM_VirtualBox_Extension_Pack-4.2.12-84980.vbox-extpack
Verify that the Extension Pack is successfully installed, by using the following command.

$ VBoxManage list extpacks
Extension Packs: 1
Pack no. 0: Oracle VM VirtualBox Extension Pack
Version: 4.2.12
Revision: 84980
Description: USB 2.0 Host Controller, VirtualBox RDP, PXE ROM with E1000 support.
Usable: true
Why unusable:
Create a VirtualBox VM from the command line

I assume that the VirtualBox' VM directory is located in "~/VirtualBox\ VMs".

First create a VM. The name of the VM is "testvm" in this example.

$ VBoxManage createvm --name "testvm" --register
Specify the hardware configurations of the VM (e.g., Ubuntu OS type, 1024MB memory, bridged networking, DVD booting).

$ VBoxManage modifyvm "testvm" --memory 1024 --acpi on --boot1 dvd --nic1 bridged --bridgeadapter1 eth0 --ostype Ubuntu
Create a disk image (with size of 10000 MB). Optionally, you can specify disk image format by using "--format [VDI|VMDK|VHD]" option. Without this option, VDI image format will be used by default.

$ VBoxManage createvdi --filename ~/VirtualBox\ VMs/testvm/testvm-disk01.vdi --size 10000
Add an IDE controller to the VM.

$ VBoxManage storagectl "testvm" --name "IDE Controller" --add ide
Attach the previously created disk image as well as CD/DVD drive to the IDE controller. Ubuntu installation ISO image (found in /iso/ubuntu-12.04.1-server-i386.iso) is then inserted to the CD/DVD drive.

$ VBoxManage storageattach "testvm" --storagectl "IDE Controller" --port 0 --device 0 --type hdd --medium ~/VirtualBox\ VMs/testvm/testvm-disk01.vdi
$ VBoxManage storageattach "testvm" --storagectl "IDE Controller" --port 1 --device 0 --type dvddrive --medium /iso/ubuntu-12.04.1-server-i386.iso
OR Detach ISO:
$ VBoxManage storageattach "testvm" --storagectl "IDE Controller" --port 1 --device 0 --type dvddrive --medium none
Start VirtualBox VM from the command line

Once a new VM is created, you can start the VM headless (i.e., without VirtualBox console GUI) as follows.

$ VBoxHeadless --startvm "testvm" &
The above command will launch the VM, as well as VRDE remote desktop server. The remote desktop server is needed to access the headless VM's console.

By default, the VRDE server is listening on TCP port 3389. If you want to change the default port number, use "-e" option as follows.

$ VBoxHeadless --startvm "testvm" -e "TCP/Ports=4444" &
If you don't need remote desktop support, launch a VM with "--vrde off" option.

$ VBoxHeadless --startvm "testvm" --vrde off &
Connect to headless VirtualBox VM via remote desktop

Once a VM is launched with remote desktop support, you can access the VM's console via any remote desktop client (e.g., rdesktop).

To install rdesktop on Ubuntu or Debian:

$ sudo apt-get install rdesktop
To install rdesktop on CentOS, RHEL or Fedora, configure Repoforge on your system, and then run the following.

$ sudo yum install rdesktop
To access a headless VM on a remote host machine, run the following.

$ rdesktop -a 16 IP_address_host_machine
If you use a custom port number for a remote desktop server, run the following instead.

$ rdesktop -a 16 IP_address_host_machine:port_number

Create Own CA


Create your private certificate authority (CA)
Creating a private CA can be useful if you have a lot of services encrypting data for internal use but don’t need the domain to be verified by a public CA like Verisign, Thawte etc. By importing the CA to all computers that will use these services users won’t get the a popup in IE and Firefox saying that the certificate is invalid.

1. Create a CA certificate

Create a private key for your CA:

openssl genrsa -des3 -out ca.key 4096

You will need to enter passphrase, this password will be used everytime you sign a certificate with this CA

Make sure unauthorized users don’t get access to your private key:

chmod 700 ca.key

Create the certificate, this will be shown as the top level certificate when you have signed other certificates so choose expiration day and the certificate contents carefully. All signed certificates will expirate if the top level certificate expires so you may want to choose a few years here

openssl req -new -x509 -days 3650 -key ca.key -out ca.crt

Here is a sample of input values:

Enter pass phrase for ca.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Debian Tutorials
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:Debian Tutorials CA
Email Address []:

Common name will be shown when users are displaying details about the certificate

2. Create a certificate request

Create a private key:

openssl genrsa -des3 -out 4096

Replace by your domain name

Create the certificate request

openssl req -new -key -out

Make sure you put your domain name in the “Common Name” field

3. Sign the certificate with your CA certificate

You will need to provide the certificate request here and the CA key

openssl x509 -req -days 365 -in -CA ca.crt -CAkey ca.key -set_serial 01 -out

4. Remove password from key (optional)

If using the certificate with Apache, Postfix or other services you may need to replace the password in your private key so that the service can start without user interaction

openssl rsa -in -out

Set permissions on the keys

chmod 700
chmod 700

Mysql Master-Master with many slaves replication


Using Master<->Master replication is good backup solution, but is not good enough if we want to offload queries from master.

Thus we can create:
Master - Master
| |
Slave-Slave Slave-Slave

1. Setup both masters.
Tweak some options in my.cnf (on all masters!):
server-id = 1
log-bin = /var/log/mysql/bin.log
log-bin-index = /usr/local/mysql/var/log-bin.index
log-error = /usr/local/mysql/var/error.log
expire_logs_days = 10
max_binlog_size = 200M

WARNING: log-slave-updates is crucial!!! If not set slaves on second node won't get updated and vice versa if pushed from first master.

2. Add MySQL Users:
mysql> grant replication slave on . to 'replication'@'10.0.0.%' identified by 'pass';
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

3. Dump all DBs from master. SCP dump on slave and import it. This way we will have 1:1 dbs on both nodes. Note that you may set password for debian-sys-maint user in /etc/mysql/debian.cnf

On master:
$> mysqldump --delete-master-logs --master-data --lock-all-tables --all-databases --hex-blob -u root -p > dumpall.sql
$> bzip2 dumpall.sql
$> scp dumpall.sql.bz2 root@slave:

NOTICE: --delete-master-logs clears all master logs BEFORE this dump. If you have other slaves syncin' or need earlier binlogs remove this option!

On slave:
$> bunzip2 dumpall.sql.bz2
$> mysql -uroot -p mysql < dumpall.sql


$> grep BIN_LOG dumpall.sql

now login in mysql and change master to:

mysql> change master to master_host = '', master_user='replication', master_password='pass', master_log_file='node1-binary.000001', master_log_pos=1;
mysql> start slave;

Check if 2nd Master slave is running. Check seconds behind. Should be 0 and Error_* too. Usually this means everything is OK.
mysql> show slave status\G
mysq> show master status;

Now do the same thing on 1st Master. Just use second master bin log and position.

mysql> change master to master_host = '', master_user='replication', master_password='pass', master_log_file='node1-binary.000001', master_log_pos=1;
mysql> start slave;

Check if 1st Master slave is running. Check seconds behind. Should be 0 and Error_* too. Usually this means everything is OK.
mysql> show slave status\G

Now test create/insert/update/delete.
First on 1st master create table. Insert a record. Check on 2nd master if table is there and has record.
On second master insert second record. Check on 1st if there are 2 records.

4. Create Read-Only Slaves connected to the 1st master and on 2nd:

Simply do same setup as above. Dump DB. populate, then change master to BUT WATCH OUT for the binlog/position!

When done settiing up and slave status shows 0 TEST!

First create table on 1st master, insert 1 record.
Then Check on all slaves connected to 1st master.
After Check all slaves connected to 2nd master!
All MUST have table+record.
After that test to insert second row on 2nd slave.
Then Check on all slaves connected to 1st master.
After Check all slaves connected to 2nd master!

I think that's all!
Happy replicating.

Symfony2 Sonata Admin sonata_type_collection inline editing hidden field

Here I've found the answer to my simple question: How to inline edit a dependend one to many field without showing the parent as select box.

Here is a brief answer: Use prePersist / preUpdate methods in ParentAdmin.php class.
// in the ParentAdmin class

public function prePersist($promotion)
foreach ($promotion->getRules() as $rule) {

public function preUpdate($promotion)
foreach ($promotion->getRules() as $rule) {

Yes indeed, the sonata admin class allows for prePersist and preUpdate calls that allows us to set the promotion for the rule before persisting. Of course don’t forget to declare your admin classes as services in your configs. Other than that, I hope that this helps somebody out there.

OpenDKMI+Postfix on Debian

Original link:
Article By Chris Pentago

Goal of this how-to: Step to step guide on how to setup OpenDKIM with postfix on Debian GNU/Linux to send signed email from your VPS.

There are numerous methods or techniques that you can use to achieve email message signing. Good examples are DomainKey as well as DKIM which is an abbreviation for DomainKeys Identified Mail.

DomainKeys Identified Mail (DKIM) lets an organization take responsibility for a message that is in transit. The organization is a handler of the message, either as its originator or as an intermediary. Their reputation is the basis for evaluating whether to trust the message for further handling, such as delivery. Technically DKIM provides a method for validating a domain name identity that is associated with a message through cryptographic authentication.

These two techniques will not use symmetric encryption but rather will employ asymmetric encryption. (more info: In both methods, the common algorithm used is RSA. This algorithm is also the default for these methods of achieving email message signing.

For those wondering about what asymmetric means, the following is a detailed explanation. It is a technique that utilizes a key to sign the email message. Other methods will not require a key. One can have two types of keys: a private key and a public key. These keys will come into play to verify the message as well. The two methods of creating email message signing as highlighted above are filters for SMTP server. DomainKey works with a dk-filter although this filter has been discontinued in the market. OpenDKIM has become the preferred replacement where filters are concerned.

A mail server must be enabled with a filter to set up the server properly. In light of this, Postfix can be used because it is enabled accordingly. Another requirement is the freedom to add or change the DNS records as you desire. With the above in mind, the following is a step by step guide on how to set up Postfix email server with DomainKey Indentified Mail on Debian.

1. The first thing is to update your software if you do not have Postfix installed already. Look at the manual provided to know exactly how to install the software. Once you have it running, move on to the next step.

On Debian, issue these commands:

aptitude update
aptitude safe-upgrade

2. At this point, it is important to install the DKIM filter. As hinted above, the most common and available filter is OpenDKIM. Installing this filter is not complicated at all and should not take much time.

aptitude install opendkim opendkim-tools

3. The next step involves setting up a directory for the storage of private keys. You can have as many domains as you wish but make sure that the permission settings are in order because they are the most critical.

mkdir -pv /etc/opendkim/
chown -Rv opendkim:opendkim /etc/opendkim
chmod go-rwx /etc/opendkim/

4. Here, security is pivotal and it will warrant you to create a key pair for each domain you have. In other words, every single domain should have a key pair and this is the way to go.

cd /etc/opendkim/
opendkim-genkey -r -h rsa-sha256 -d -s mail
mv -v mail.private mail
chown opendkim:opendkim

chmod u=rw,go-rwx

5. The next thing to do is to publish a public key using the DNS record. You will be required to insert new TXT DNS record with key generated previously. You’ll be presented with key in Bind (DNS Server) format but it’s easy to paste necesary parts to your domain’s DNS provider: IN TXT "v=DKIM1; h=rsa-sha256; k=rsa;p=AySFjB......xorQAB"

Example on how it look in CloudFlare’s DNS manager:


6. At this juncture, it is vital to set up the key table. You will do this by using a specified format:

KeyID Domain:Selector:PathToPrivateKey

So fire up your text editor of choice and open/create /etc/opendkim/KeyTable file our example looks like this:

7. The next step involves setting up the signing table. The filter used is programmed to read the table by looking for matched domain. Again, open/create /etc/opendkim/SigningTable in your favorite text editor and put this into it:

8. You will then have to create a /etc/opendkim/TrustedHosts file at this point. It will list the top trusted hosts as you desire. Again, the format used can be as given earlier when creating a signing table as well as a key table. (this is DNS server you'll get from your provider)

9. Next, set up the ownership of files we just created:

chown opendkim:opendkim /etc/opendkim/KeyTable
chown opendkim:opendkim /etc/opendkim/SigningTable
chown opendkim:opendkim /etc/opendkim/TrustedHosts

10. This step is critical because it involves configuring the OpenDKIM filter to read the files that you have created above. Do this by opening /etc/opendkim.conf using your chosen editor. Consequently, it might be good to delete the Debian configuration so that you can replace it with the new and edited information.

# Enable Logging
Syslog yes
SyslogSuccess yes
LogWhy yes

# User mask
UMask 002

# Always oversign From (sign using actual From and a null From to prevent malicious signatures header fields (From and/or others) between the signer and the verifier)

OversignHeaders From

# Our KeyTable and SigningTable
KeyTable refile:/etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable

# Trusted Hosts
ExternalIgnoreList /etc/opendkim/TrustedHosts
InternalHosts /etc/opendkim/TrustedHosts

# Hashing Algorithm
SignatureAlgorithm rsa-sha256

# Auto restart when the failure occurs. CAUTION: This may cause a tight fork loops
AutoRestart Yes

# Set the user and group to opendkim user
UserID opendkim:opendkim

# Specify the working socket
Socket inet:8891@localhost

11. It is now time to change or configure the OpenDKIM filter on Postfix. This can be done by simply altering some parameters to achieve what you require. It is very important to do this carefully so that you avoid any errors that may come up later. Open /etc/postfix/ and add/uncomment these lines:

# OpenDKIM
milter_default_action = accept
milter_protocol = 2
smtpd_milters = inet:localhost:8891
non_smtpd_milters = $smtpd_milters

12. When you reach this step, you are almost there. You will however be required to restart OpenDKIM service as well as Postfix. After doing this, make sure that everything is fine for you to move on to the final step.

service opendkim start

13. The final step is to check whether the changes you were making have turned out well. Check if OpenDKIM service is online and listens on port we defined above.

ps aux | grep dkim
netstat -tanp | grep dkim

This method works like a charm and it is the sure way to attain email messaging signing. It is really not a complicated process but you will need to follow the method to the letter. Beyond the technical jargon, any person willing to follow this guide diligently can achieve success. Keep in mind that the top benefits of DKIM is to curb abuse as well as to reduce spamming to recipients.

It is a method to verify how genuine an organization or a domain is. There are many other elements that will play a good role in helping your business or domain establish a credible name in the market through this process.

This is especially important if you plan to send email from your server outside to GMail or Hotmail servers with increased security/spam filters or your mail may end up sent to SPAM folder or even rejected.

If you followed the procedure but still unable to send mail to GMail for instance, ask your web host to set you up with ReverseDNS so those mail receiving servers could match message header IP address with your domain.

If your VPS or dedicated server are located in highly available and secure government data centre such as Macquarie’s or TheBunker’s, these indetifying features might be already set by default for their new customers.

OpenSSL mostly used commands

Here's a list of mostly used openssl commands:

1. Create key + csr:

$> openssl req -new -nodes -keyout server.key -out server.csr -newkey rsa:4096

2. Create key only:

$> openssl genrsa -des3 -out server.key.crypted 4096

3. Remove password from key:

$> openssl rsa -in server.key.crypted -out server.key

4. Generate CSR

$> openssl req -new -key server.key -out server.csr

5. Self generated certificate

$> openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

6. View the details of CSR

$> openssl req -noout -text -in server.csr

7. Check a Certificate Signing Request (CSR)

$> openssl req -text -noout -verify -in CSR.csr

8. Check a private key

$> openssl rsa -in privateKey.key -check

9. Check a certificate

$> openssl x509 -in certificate.crt -text -noout

10. Check a PKCS#12 file (.pfx or .p12)

$> openssl pkcs12 -info -in keyStore.p12

11. Convert .crt to .pfx for IIS server

$> openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt

How do I extract information from a certificate? (from: )

An SSL certificate contains a wide range of information: issuer, valid dates, subject, and some hardcore crypto stuff. The x509 subcommand is the entry point for retrieving this information. The examples below all assume that the certificate you want to examine is stored in a file named cert.pem.

Using the -text option will give you the full breadth of information.

$> openssl x509 -text -in cert.pem
Other options will provide more targeted sets of data.

# who issued the cert?
$> openssl x509 -noout -in cert.pem -issuer

# to whom was it issued?
$> openssl x509 -noout -in cert.pem -subject

# for what dates is it valid?
$> openssl x509 -noout -in cert.pem -dates

# the above, all at once
$> openssl x509 -noout -in cert.pem -issuer -subject -dates

# what is its hash value?
$> openssl x509 -noout -in cert.pem -hash

$> openssl x509 -noout -in cert.pem -serial

# what is its MD5 fingerprint?
#> openssl x509 -noout -in cert.pem -fingerprint -md5

# what is its SHA1 fingerprint?
$> openssl x509 -noout -in cert.pem -fingerprint -sha1

Monit example configurations.