L'uso di questo sito
autorizza anche l'uso dei cookie
necessari al suo funzionamento.
(Altre informazioni)
Showing posts with label linux. Show all posts
Showing posts with label linux. Show all posts

Wednesday, December 23, 2015

Using Linux LVM snapshots to run "experiments" on VMs


I am going to show how to create a LVM (Logical Volume Manager) snapshot and use it to return its base to a previous state.

This is useful for experiments, e.g on a LVM-based virtual machine (VM):
  • take a partition snapshot of the FS where the VM lives.
  • experiment with the VM (make config changes etc.)
  • if your tests are successful, lvremove the snapshot and keep the experiment's results
  • if you want to discard the tests, stop the VM then lvconvert –merge -v <snapshot> will restore the partition to its snapshot state.

Check required capabilities

# dmsetup targets
zero             v1.1.0
mirror           v1.13.2
snapshot-merge   v1.3.0
snapshot-origin  v1.9.0
snapshot         v1.13.0
striped          v1.5.1
linear           v1.2.1
error            v1.3.0

For the rest of the tutorial to work, we need the snapshot-merge target to exist.
If (as it happened to me) you run this on a machine with no kernel support for merging, you will be stumped in the last passage (lvcreate –merge). You can get out of this pickle by either:
  1. Grabbing a Live DVD of a distribution that has merge support
  2. run the last step from the live environment
or:
  1. Boot rescue from a distribution that has merge support
  2. Do not mount the LV partitions involved when/if asked
  3. run the last step from the rescue environment
While the first course of action worked perfectly in my case, it is the second one that redhat reccommends. When I tried it, however, the rescue environment was missing the required device files /dev/SataGroup and I could not proceed.

Create volume, make a filesystem, mount it.

# lvcreate --size 100m -n test SataGroup01
# mkfs.ext2 /dev/SataGroup01/test
# mkdir /tmp/test
#  mount /dev/SataGroup01/test /tmp/test
# cd /tmp/test
# ls
# mkdir a{0..2}
# ls
a0  a1  a2   lost+found
# for i in {0..2}; do touch a$i/b$i ; done
# ls a0
b0

Create a snapshot on the base volume, then mount it.

When the snapshot is created, care must be taken to make a large enough snapshot to avoid filling it. If the snapshot fills up, you will end up with a stuck snapshot and you'll have to go to hell and back to get rid of it (I may show how in a followup post).

# lvcreate --snapshot --size 100m -n test-snap /dev/SataGroup01/test
# mkdir /tmp/test-snap
# mount /dev/SataGroup01/test-snap /tmp/test-snap
The contents of the volumes are identical:
# ls /tmp/test
a0  a1  a2 lost+found
[root@cane test]# ls /tmp/test-snap/
a0  a1  a2 lost+found
Change them in different ways:
# mkdir /tmp/test/b0
# rm -rf  /tmp/test/a1
# mkdir /tmp/test-snap/c0
# ls /tmp/test*
/tmp/test:
a0  a2  b0  lost+found

/tmp/test-snap:
a0  a1  a2 c0  lost+found

Now unmount them:


# umount /tmp/test
# umount /tmp/test-test snap

End the experiment

If we now throw away test-snap, we'd be left with the changes done in test. If we want to back up our changes, and keep what was done in snap instead, do:

# lvconvert --merge -v /dev/SataGroup01/test-snap 
    Using logical volume(s) on command line.
    Archiving volume group "SataGroup01" metadata (seqno 41).
    Loading SataGroup01-test-real table (253:14)
    Suppressed SataGroup01-test-real (253:14) identical table reload.
    Loading SataGroup01-test--snap-cow table (253:15)
    Suppressed SataGroup01-test--snap-cow (253:15) identical table reload.
    Loading SataGroup01-test table (253:16)
    Loading SataGroup01-test--snap table (253:17)
    Not monitoring SataGroup01/snapshot0
    Suspending SataGroup01-test (253:16) with filesystem sync with device flush
    Suspending SataGroup01-test--snap (253:17) with filesystem sync with device flush
    Suspending SataGroup01-test-real (253:14) with filesystem sync with device flush
    Suspending SataGroup01-test--snap-cow (253:15) with filesystem sync with device flush
    Loading SataGroup01-test-real table (253:14)
    Suppressed SataGroup01-test-real (253:14) identical table reload.
    Loading SataGroup01-test--snap-cow table (253:15)
    Suppressed SataGroup01-test--snap-cow (253:15) identical table reload.
    Resuming SataGroup01-test-real (253:14)
    Resuming SataGroup01-test--snap-cow (253:15)
    Resuming SataGroup01-test (253:16)
    Resuming SataGroup01-test--snap (253:17)
    Creating volume group backup "/etc/lvm/backup/SataGroup01" (seqno 42).
  Merging of volume test-snap started.
    Checking progress before waiting every 15 seconds
  test: Merged: 100.0%
  Merge of snapshot into logical volume test has finished.
    Archiving volume group "SataGroup01" metadata (seqno 42).
    Removing snapshot test-snap
    Loading SataGroup01-test table (253:16)
    Loading SataGroup01-test--snap table (253:17)
    Suspending SataGroup01-test (253:16) with device flush
    Suspending SataGroup01-test--snap (253:17) with device flush
    Suspending SataGroup01-test--snap-cow (253:15) with device flush
    Suspending SataGroup01-test-real (253:14) with device flush
    Resuming SataGroup01-test--snap-cow (253:15)
    Resuming SataGroup01-test-real (253:14)
    Resuming SataGroup01-test (253:16)
    Removing SataGroup01-test-real (253:14)
    Removing SataGroup01-test--snap (253:17)
    Removing SataGroup01-test--snap-cow (253:15)
    Releasing logical volume "test-snap"
    Creating volume group backup "/etc/lvm/backup/SataGroup01" (seqno 44).
  Logical volume "test-snap" successfully removed

We have kept the changes originally in the snapshot volume (which as been removed by lvconvert); a1 has come back, b0 is gone, c0 - from test-snap - is now in place:

# ls  /tmp/test/ /tmp/test/a1
/tmp/test/:
a0  a1  a2 c0  lost+found

/tmp/test/a1:
b1

Tuesday, March 24, 2015

The parable of SELinux - A sunday reading from the Book of Tar

From the Book of Tar, 1:14:

And it came to pass that, in a town in Galilee, a SysAdmin could not stomach SELinux.

And he went to talk to a security.guru, and he said unto him:

"Because of SELinux, there is much crashing amongst my daemons, and my log files are void and empty, and my data center is silent"

And the security.guru replied:

 "You have only your ignorance to blame, as SELinux will not yield  its enlightenment to those who do not pursue its intimate knowledge".

And the SysAdmin, chastened, hung his head in shame, and returned to his datacenter cave, and began studying the SELinux wisdom in earnest. But instead of enlightenment, he felt the study was growing the doubt in his heart. And it came to pass that one of the sacred books read:

"You will learn the details of the SELinux policy for your distribution". 

Ando so the SysadMin browsed its server policy and lo, the rules were thousands and their lot meaningless, and the kernel in its binary form was  crystal clear by comparison.

And the SysAdmin, with much doubt in his heart, returned to the security.guru dwelling and said unto him:

 "Surely you knew that intimate knowledge of thousands of rules is not possible and you were trying to test my resolve. Pray tell me what should I do now."

And the security.guru smiled, and told him, sternly:

 "You fool! Why do concern yourself with questions that are beyond thee? Don't you know that SELinux policies are brought to you by higher powers which you never may hope to stare upon? Return therefore to your keyboard, and relax."

But the sysadmin was sad in his heart, thinking:

"The guru advises me to study, but when study brings chaos and nonsense, he tells me to relax. But still my servers are down, and my logs are void and my datacenter suffers."

And  turning in anger to the security.guru he saith unto him:

"Surely you have been smoking bad stuff, or ate the weed that brings madness"

But the guru replied:

"Your heart is evil and your soul is now lost, because you did not abide to the Principle of least privilege." 

But the SysAdmin arose and explained to the guru, with several interesting details, what he should do with the Principle of least privilege and SELinux and its accursed lot, and advised him that returning to write windows ACLs would have brought several blessings unto him.

And the guru left with great anger and disdain, but as he left he fell in the group policies Gehenna, were there was much wailing and teeth grinding.

But the SysAdmin returned to his console and typed:

# for h in $(serverlist) ; do ssh $h setenforce 0; done 

And lo, he felt a great peace in his heart, and a soft light shone on his black and green monitor, and a sweet scent filled the cave and the buzz of the servers was loud, and the daemons were running and the logs were full and the diagnostics again meaningful, and joy returned to the datacenter.

Monday, March 23, 2015

La Parabola di SELinux

C'era in Galilea un SysAdmin che non riusciva a digerire SELinux.

Andò allora da un security.guru, che gli disse:

 "Non puoi pretendere di capire SELinux senza conoscerlo intimamente".

Il SysAdmin, umiliato, chinò la testa, tornò nella sua caverna e si procurò diversi
testi su SELinux. Iniziò a studiarli, ma, invece di sentire
l'illuminazione dentro di sè, sentiva un senso di sgomento crescere
nel suo animo.

Finchè un giorno, su uno dei testi egli lesse la frase

"è molto importante conoscere bene la policy di selinux per la vostra
distribuzione". 

Egli allora aprì il tool grafico per il browsing della
policy ed ecco, le regole erano migliaia, e la loro concatenazione era
senza senso, e sendmail.cf era chiaro come un cristallo di rocca al
confronto (e tale era anche il kernel in forma binaria).

Il SysAdmin tornò allora dal security.guru e gli disse:

 "Di certo tu sapevi che non è possibile studiare e conoscere miglialia di regole - dimmi dunque come devo procedere". 

E il security.guru gli disse:

 "Perchè ti preoccupi di queste cose? La policy di SELinux viene a te compilata da chi ne capisce". 

E il SysAdmin dubitò nel suo cuore, e pensò:

"Costui prima mi dice studia. Quando studio e trovo il non senso, mi dice di non preoccuparmi. Ma intanto i miei server languiscono e i log sono muti."

E allora volgendosi al security.guru gli disse

"Tu hai fumato molto
male".

E il guru a lui:

"Tu parli così perché il tuo cuore è perduto,
e non conosci il Principio del Minimo Privilegio".

Ma allora il SysAdmin spiegò al guru, con molti interessanti dettagli, a quali fini poteva
porre il principio del minimo privilegio, e di usare SELinux per farcisi i bigodini, e gli consigliò di tornare a scrivere ACL in Windows, che gli avrebbe arrecato giovamento. E il guru, provando grande sdegno nel suo cuore si allontanò dal SysAdmin, ma allontanandosi cadde nella Geenna delle group policies, dove per lui fu pianto e stridor di denti.

Ma il SysAdmin si volse verso la sua console e digitò:

# for h in $(serverlist) ; do ssh $h setenforce 0; done 

Ed ecco un grande senso di pace scese nel suo cuore, e i demoni
ricominciarono a funzionare e tutto fu letizia nel data center.

Thursday, February 12, 2015

Un normale pomeriggio di follia informatica

12:58 monitor di destra Acer 22", 1680x1050

12:59 xlock 

13:00 pranzo

13:58 x(un)lock 

13:59 monitor di destra zoomato, sfocato
       ಠ_ಠ
14:00 monitor [on]*[off]

14:01 ma BIOPARCO

14:02 accessibility-zoom-unzoom
       f1..f12
       shift f1..12
       shift-ctrl-alt-meta-cokebottle-f1..f12

14:07 system->displays
       monitor di destra sconosciuto, 1024x678

14:08 PORTA TUA NONNA
       reboot
       cold reboot
       [ring...]
       [ring...]
       [ring si potrebbe riavere la posta eliminata di un'oretta fa?> (wut)

15:00 google 'cinnamon linux Acer 22" lost resolution'
       (About 599,000 results)
       # cvt 1680 1050
       # xrandr --newmode  "1680x1050_60.00"  146.25  1680 1784 ...
       # xrandr --addmode VGA-0 "1680x1050_60.00"
       # arandr
       (cursecursecursecurse)
       [mailstorm]
       [provision hosting]
       [ring..."Scusi ma lei mi può far capire chi è anonymous?"]
       (mi fanno male gli occhi - forse è il monitor)
       EDID?
       # less /var/log/Xorg.log
       # zless /var/log/Xorg*.*log*

16:00 OK, generiamo xorg.conf 
       reboot
       cold reboot
       xorg.conf EPIC FAIL (strano, non capisco come mai)
       # rm /etc/X11/xorg.conf
       reboot

16:45 ricerca altro monitor (no)
       comincia ordine monitor nuovo
       [sospetto - pink panther theme]
       disconnetti cavo di alimentazione monitor dx
       riconnetti cavo di alimentazione monitor dx

16:55 monitor di destra Acer 22", 1680x1050

17:00 rage⚓tilt⚓cringe⚓rage⚓cringe⚓tilt@#☽☾!⚒
     [ring...]

       

Thursday, October 9, 2014

User support: lo strano caso dell'imap silenzioso


C: "Come si riavvia il server di posta nostro, qui? Perché c'è un problema, sembra che gli utenti non si colleghino più a imap"

BOFH:"Fammi vedere *clikety clik*"

C:"Ma intanto dimmi, sto yum ha un -purge per i pacchetti non usati. Parché apt-get..."

BOFH:"(Uh??) Ma sai, funzionano diversamente e..."

C:"Perché sai oggi ho fatto degli update e c'erano dei pacchetti che non servivano"

BOFH: (Appuntendo le orecchie) "Per caso uno si chiamava dovecot?"

C:"Nooooo ho tolto mysql, ma che, dici che ci saranno state delle dipendenze?"

BOFH:"Hai cancellato il server imap. Anche quello POP3, prima che tu me lo chieda."

....

Friday, August 8, 2014

A simple command line remainder, for the linux GUI

One of the first exercises of the Unix (then: Linux) books of yore was using the "at" command to create reminders (or, alarms). If memory serves, it went like this:

$ echo "echo \"Go home!\" > /dev/tty " | at 17:00

Because this is way too much typing, you were then taught how to plop it in a /usr/local/bin script:

alarm.sh:

       #!/bin/sh
       echo "echo \"$1\" > /dev/tty" |  at $2

Those were the tty days. Enter the GUI (or, even, multiple terminals) and your nifty alarm utility does not cut it any more, essentially because you're not usually looking at the right window when the alarm is echoed. Using xdialog or knotify in place of echo does not cut it either, as both rely on being able to connect to the X display (which they cannot do, because they are activated by atd outside the current desktop session).

Of course there must be thousands of fancy reminder/alarm apps from the desktop to the web-based, but none (that I could find) that'd allow me to set a simple reminder by typing it in the terminal I happen to have my focus on.

Enter libnotify and its command line minion notify-send:

alarm.sh:

#!/bin/bash

TITLE=$3
[[ x$TITLE == x ]] && TITLE="Sveglia!!!!"
echo /usr/bin/notify-send  -u critical  \"$TITLE\" \"$2\"\
 |at -m "$1"

And then:

$ alarm.sh 13:00 "Aren't you hungry?" "Lunch time" 

The -m switch tells at to send you mail when it fires  - Fedora pre 20 users may want to take notice of this bug report and compensate accordingly. Of course, the atd service must be running for this to work.

Wednesday, May 21, 2014

Sendmail and procmail mailer for egress mail filtering.

Ok, this is basically an annotated version of recipe 6.8 from O'Reilly's sendmail cookbook. As a bonus, though, it contains also a useful (if spooky) working example AND the relevant procmail configuration. It takes about a day to setup and test without guidance, so enjoy. If you need to be told how to rebuild sendmail.cf from .mc or what is mailertable, this post will be Tralfamadorian to you - go read the Bat Book.

The italian version is here.

Summary

  • Create the sendmail configuration to use mailertable and the procmail mailer.
/etc/mail/sendmail.mc
dnl Enable support for the mailertable
FEATURE(`mailertable')
dnl Add procmail to the list of available mailers
MAILER(procmail)
  • Ath the bottom, insert local rules to fend off loops (watch out for the TAB between '>' e '$')
/etc/mail/sendmail.mc
LOCAL_CONFIG
# Add .PROCMAIL to the pseudo-domain list
CP.PROCMAIL
LOCAL_RULE_0
# Strip .PROCMAIL and send via esmtp
R$+ < @ $+ .PROCMAIL . >        $#esmtp $@ $2 $: $1<@$2>
  • Set up mailertable to route mail sent to specific domains (or even all mail, as in the last line) through the procmail mailer:
/etc/mail/mailertable
example.com       procmail:/etc/mail/procmailrcs/spam-filter
wrotethebook.net  procmail:/etc/mail/procmailrcs/spam-filter
fake.ora.com      procmail:/etc/mail/procmailrcs/uce-filter
.                 procmail:/etc/mail/procmailrcs/any.rc
  • Create procmail recipe files (owned by root.root, perms 644) in  /etc/mail/procmailrcs (root.root, perms 755). Forwarded mail should extend with the .PROCMAIL pseudo-domain all addresses liable to be rerouted through the procmail mailer.

Discussion and example

The procmail mailer and mailertable

The MAILER(procmail) macro adds the  procmail mailer defintion. This mailer is independent and separate form the local_procmail feature (used to filter incoming local mail).

Using the mailer requires routing mail to it through mailertable:
/etc/mail/mailertable
example.com       procmail:/etc/mail/procmailrcs/spam-filter
.                 procmail:/etc/mail/procmailrcs/any.rc
First rule sends mail going to example.com to the rules defined in spam-filter, the second line sends all mail to any.rc.

# sendmail -bv crooks@example.com
crooks@example.com... deliverable: mailer procmail, host /etc/mail/procmailrcs/spam-filter, user crooks@example.com
# sendmail -bv spammers@spammers.net
spammers@spammers.net... deliverable: mailer procmail, host /etc/mail/procmailrcs/any.rc, user spammers@wrotethebook.net

sendmail invokes procmail as follows:


procmail -Y -m $h $f $u

The -Y flag selects Berkely Unix mailbox format, -m tells procmail that it's being invokde as a general mail filter, $h is set to the full path of the rule file, $f is set to the envelope sender address, $u to the envelope recipient address: these last two can ber referenced in tha rc file as $1 and $2.

Local rules

If, after processing, the message is going to be forwarded again, care must be taken as to avoid mail loop when (if) the message gets back to mailertable processing. The standard technique is to add the pseudo domain .PROCMAIL to the  recipient address within the procmail recipe files, and intercept this domain within sendmai.cf  adding rules to the bottom of  sendmail.mc like this (there must be  a literal  TAB between '<' and '$'):
/etc/mail/sendmail.mc

LOCAL_CONFIG
# Add .PROCMAIL to the pseudo-domain list
CP.PROCMAIL
LOCAL_RULE_0
# Strip .PROCMAIL and send via esmtp
R$+ < @ $+ .PROCMAIL . >        $#esmtp $@ $2 $: $1<@$2>

  • LOCAL_CONFIG starts the section that will be copied to sendmail.cf verbatim;
  • CP.PROMAIL inserts .PROCMAIL in class P: pseudo-domains that sendmail does not look up in the DNS;
  • LOCAL_RULE_0 starts a section whose content is added to  ruleset 0—also called the  parse ruleset. The code is entered in the  ParseLocal ruleset (ruleset 98). The parse ruleset risolvs an addresse in a delivery triplet.
  • The R rule matches addresses of the form user@domain.PROCMAIL, and rewrites them as a triplet with with “esmtp”, as mailer, “domain” as hast and “user@domain” as recipient.
 After regenerating sendmail.cf, we have:

# sendmail -bv crooks@example.com.PROCMAIL
crooks@example.com.PROCMAIL... deliverable: mailer esmtp, host example.com, user 
crooks@example.com

Procmail rule files, and an example


The  (objectionable) purpose of this example is creating a sendmail instance who does a stealth forward of a copy of all transient mail to a set of configured addresses, while also delivering it to the intended address.
  • /etc/mail/sendmail.mc is as above.
  • Mailertable:
/etc/mail/mailertable
.                 procmail:/etc/mail/procmailrcs/any.rc
/etc/mail/procmailrcs has perms 755, owner root.root; the files within, 644, root.root. SELinux users: no doubt SELinux will mess this up, as it does with everything else when it's turned on - I can offer no guidance, suit yourselves as best you can.
  • We use two auxiliary rule files to set-up and tear down tha stage.
/etc/mail/promailrcs/000_setup

# Debugging (use =no and =no to turn off)
VERBOSE=on
LOGABSTRACT=all
#
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
LOGFILE=/var/log/proc_log   #recommended
#this is clearer
OSENDER=$1
ORECIPIENT=$2
#Echoed to logfile at the end
TRAP="echo '---------- End of procmailer ------' "
#
# Antiloop belt+suspender. This should never be triggered.
:0 w
* 1^0 ^X-Our-Anti-Loop: SET
! -f $OSENDER $ORECIPIENT.PROCMAIL
000_setup must be included before any other ruel: besides some standard setting, it copies $1 and $2 to the more mnemonic $OSENDER, $ORECIPIENT and checks wether a header tht we add on exit exists (it should never be present): if it does it shortcircuits the processing with a copy of the final rule. This is also found in the file 999_end:
/etc/mail/promailrcs/999_end
#
# Insert Anti-loop header, add .PROCMAIL to recipient
:0 w
| (formail \
  -A"X-Our-Loop: SET" \
  ) | $SENDMAIL -oi -f $OSENDER $ORECIPIENT.PROCMAIL
the message is sent to the final recipient, after .PROCMAIL has been tacked to the recipient address, to trigger the sendmail.cf rules. This file must be included at the very end.
  • In any.rc is where the meat and potatoes are:
/etc/mail/promailrcs/any.rc

# Setup 
INCLUDERC=/etc/mail/procmailrcs/000_setup
#
#flag 'c' creates a carbon copy for processing
# Avoid sending duplicates
:0 Whc
| formail -D 16384 /tmp/idcache
#
#flag 'c' creates a carbon copy for processing
#flag 'e' executes only if previous command failed.
#espiones must contain addresses that are either local or .PROCMAIL terminated
:0 ec
| (formail -A"X-Our-Processed: SET" ) | $SENDMAIL -oi -f $OSENDER espiones
#clean up and forward
INCLUDERC=/etc/mail/procmailrcs/999_end

After setup, the second rule  checks if the message ID is already in a cache file, and add it there if it isn't. This will avoid sending multiple copies of the message to the  “espiones” when we have several recipients  (in  from:,  cc: or bcc:). Lastly the message gets added a watermark header, for debugging.
  • Since espiones is an aliased adress, non-local addresses in the alias need protection, too (as would literal addresses specified in the rule)
/etc/aliases
      espiones: foo@bar.com.PROCMAIL, baz@sna.fu.PROCMAIL, snafu
snafu, being local, is not  .PROCMAIL protected.

Additional Considerations

No doubt a task like this could be performed with a milter. Usage of the procmail mailer, as everything,  has pros and cons.

Pros

  • You do not need to select, write, or buy a suitable milter
  • Yu do not have to learn the ins and outs of yet another piece of MTA related software
  • You do not have to set up/debug the relevant communication between milter and sendmail
  • You have one less demon (the milter) to take care of

Cons

  • The mail flow becomes more involved and it is now controlled by yet another layer of configuration files (the rule files), and the same message will go through sendmail more than once. 
  • God help you if you come to rely on multiple loops of this machinery (it is tempting, I know).
  • Procmail syntax sucks.

Tuesday, May 20, 2014

Sendmail e procmail mailer per il filtraggio della posta in uscita

Ok, questa è più o meno la ricetta 6.8 dal sendmail cookbook, annotata. Però contiene anche la parte di procmail, è testata e funziona - e farlo senza guida richiede una giornata e giù di lì, quindi... enjoy.

Sommario

  • Creare la configurazione di sendmail per utilizzare mailertable e il mailer procmail, come segue.
/etc/mail/sendmail.mc
dnl Enable support for the mailertable
FEATURE(`mailertable')
dnl Add procmail to the list of available mailers
MAILER(procmail)
  • Inserire regole locali per permettere il reinvio di posta senza loop (attenzione al TAB tra '>' e '$')
/etc/mail/sendmail.mc
LOCAL_CONFIG
# Add .PROCMAIL to the pseudo-domain list
CP.PROCMAIL
LOCAL_RULE_0
# Strip .PROCMAIL and send via esmtp
R$+ < @ $+ .PROCMAIL . >        $#esmtp $@ $2 $: $1<@$2>
  • Usare mailertable per inviare la posta di domini specifici (o tutti i domini) al mailer procmail (l'ultima linea si applica a tutta la posta):
/etc/mail/mailertable
example.com       procmail:/etc/mail/procmailrcs/spam-filter
wrotethebook.net  procmail:/etc/mail/procmailrcs/spam-filter
fake.ora.com      procmail:/etc/mail/procmailrcs/uce-filter
.                 procmail:/etc/mail/procmailrcs/any.rc
  • Nel direttorio /etc/mail/procmailrcs creare i file per filtrare la posta, ricordandosi di estendere gli indirizzi dei destinatari finali con lo pseudodominio .PROCMAIL

Discussione ed esempi

Il mailer procmail e mailertable

La macro MAILER(procmail) aggiunge la definizione del procmail mailer. Questo è completamente separato ed indipendente dalla feature local_procmail (che si può usare per filtrare la posta in ingresso)
La macro MAILER(procmail) non aggiunge codice alla configurazione, e per usare il mailer stesso bisogna usare mailertable o aggiungere regole a sendmail.cf
/etc/mail/mailertable
example.com       procmail:/etc/mail/procmailrcs/spam-filter
.                 procmail:/etc/mail/procmailrcs/any.rc
Delle 2 regole nell' esempio qui sopra, la prima passa lapost diretta ad example.com alle regole contenuti in spam-filter, la seconda passa tutta l'altra posta alle regole in any.rc.

# sendmail -bv crooks@example.com
crooks@example.com... deliverable: mailer procmail, host /etc/mail/procmailrcs/spam-filter, user crooks@example.com
# sendmail -bv spammers@wrotethebook.net
spammers@wrotethebook.net... deliverable: mailer procmail, host /etc/mail/procmailrcs/any.rc, user spammers@wrotethebook.net

sendmail chiama procmail dal mailer mailer nel modo seguente

procmail -Y -m $h $f $u

Il flag -Y selezione il formato Berkeley Unix mailbox; il flag -m invoca procmail come un filtro di posta di uso generale. $h contiene il path del file di regole, $f è il valore dell'envelope sender (mittente) del messaggio, $u quello dell'envelope recipient (destinatario) del messaggio: nel file rc essi possono essere referenziati come le variabili $1 e $2.

Regole locali

Se l'intento è tornare ad inviare la posta dopo il filtraggio, bisogna proteggersi dai loop che si possono provocare rientrando nel mailer procmail inavvertitamente; per fare ciò, aggiungiamo lo pseudodominio .PROCMAIL all'indirizzo del destinatario utilizzando le regole di procmail: in questo modo il messaggio no sarà mai selezionato tra quelli di mailertable. Ecco le regole da aggiungere in fondo a /etc/mail/sendmail.mc (attenzione al TAB tra '>' e '$'):
/etc/mail/sendmail.mc

LOCAL_CONFIG
# Add .PROCMAIL to the pseudo-domain list
CP.PROCMAIL
LOCAL_RULE_0
# Strip .PROCMAIL and send via esmtp
R$+ < @ $+ .PROCMAIL . >        $#esmtp $@ $2 $: $1<@$2>

  • La macro LOCAL_CONFIG delimita una sezione che sarà aggiunta a sendmail.cf verbatim;
  • CP.PROMAIL inserisce .PROCMAIL nell classe P degli pseudodomini che sendmail non cercherà di risolvere via DNS.
  • La macro LOCAL_RULE_0 dà inizio alla sezione di codice da aggiungere al ruleset 0—more - anche detto il parse ruleset; questo codice farà parte del ParseLocal ruleset (anche detto ruleset 98). L'intento del parse ruleset è risolvere l'indirizzo di consegna nella tripla di consegna della posta.
  • Il comando R riconosce indirizzi della forma user@domain.PROCMAIL, riscrivendoli in una tripla con mailer “esmtp”, host uguale a “domain” e destinatario “user@domain”. Dopo aver rigenerato la configurazione, si dovrà vedere:

# sendmail -bv crooks@example.com.PROCMAIL
crooks@example.com.PROCMAIL... deliverable: mailer esmtp, host example.com, user 
crooks@example.com

Regole di procmail


Passiamo ora ad un esempio completo. Lo scopo (discutibile) è la creazione di un'isanza di sendmail che inoltri tutti i messaggi che transitano per la macchina a indirizzi terzi.
  • Il file /etc/mail/sendmail.mc è come sopra
  • Mailertable:
/etc/mail/mailertable
.                 procmail:/etc/mail/procmailrcs/any.rc
il direttorio /etc/mail/procmailrcs ha diritti 755, proprietario root.root; i file in esso contenuti, 644, root.root
  • Utilizziamo regole a carattere generale per organizzare l'ambiente.
/etc/mail/promailrcs/000_setup

# Per debugging (usare =no e =no per spegnerle)
VERBOSE=on
LOGABSTRACT=all
#
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
LOGFILE=/var/log/proc_log   #recommended
#per non confondersi
OSENDER=$1
ORECIPIENT=$2
#Viene scritta nel logfile alla fine.
TRAP="echo '---------- End of procmailer ------' "
#
# Controllo antiloop: usiamo cintura e bretelle - di qui non si dovrebbe passare mai
:0 w
* 1^0 ^X-Our-Anti-Loop: SET
! -f $OSENDER $ORECIPIENT.PROCMAIL
000_setup dev'essere incluso prima di iniziare la manipolazione della posta. Setta alcune direttive standard, assegna le variabili $1 e $2 ad altre due variabili più mnemonice (OSENDER, ORECIPIENT) e controlla l'esistenza di un header che viene settato anche all'uscita - terminando in questo caso il processing replicando quello che avrebbe dovuto fare la regola finale, che nel file 999_end:
/etc/mail/promailrcs/999_end
#
# Controllo antiloop
:0 w
| (formail \
  -A"X-Our-Anti-Loop: SET" \
  ) | $SENDMAIL -oi -f $OSENDER $ORECIPIENT.PROCMAIL
inoltra il messaggio al destinatario finale, dopo aver concatenato lo pseudo dominio .PROCMAIL per attivare le regole inserite poco sopra in sendmail.cf.
  • In any.rc si includono all'inizio e alla fine i file di cui sopra: tra i due si effettua l'inoltro in copia:
/etc/mail/promailrcs/any.rc

# Setup generale
INCLUDERC=/etc/mail/procmailrcs/000_setup
#
#flag 'c' creates a carbon copy for processing
#Evita i duplicati per indirizzi multipli
:0 Whc
| formail -D 16384 /tmp/idcache
#
#flag 'c' creates a carbon copy for processing
#flag 'e' executes only if previous command failed.
#espiones must contain addresses that are either local or .PROCMAIL terminated
:0 ec
| (formail -A"X-Our-Processed: SET" ) | $SENDMAIL -oi -f $OSENDER espiones
#clean up and forward
INCLUDERC=/etc/mail/procmailrcs/999_end
Il file 000_setup (q.v.) sistema l'ambiente; la seconda regola controlla che l'ID del messaggio corrente non sia in un file di cache (e lo aggiunge se manca). Questo server ad evitare di inviare agli “espiones” tante copie del messaggio quanti sono i destinatari (nel from:, o nel cc: o nel bcc:). Infine viene aggiunto un header che consenta l'identificazione di questo passaggio (a fini di debug).
  • I messaggi saranno inviati in copia ad un alias; gli indirizzi non locali vanno essi stessi protetti:
/etc/aliases
      espiones: foo@bar.com.PROCMAIL, baz@sna.fu.PROCMAIL, snafu
L'unico alias non protetto dall'estensione .PROCMAIL è snafu, che viene riconosciuto come locale e quindi non attiva mailertable. 

Wednesday, April 23, 2014

Admin password generation for phplist3

In phplist, starting (at least) with  version 3 admin passwords are stored as hashed values. The hashing technique is specified in phplist's config file:

define("ENCRYPTION_ALGO",'sha256');

Here the default algorithm is sha256 (but others, such as md5 or sha512 could be used). Because mysql does not offer all of these as builtins, something is needed to generate this value as a useful  way to reset admin passwords, when they are lost/forgotten (which is every time they are needed).

Google, was not helping, so I rolled my own.

A php script containing something along the lines of:

print hash('sha256',$PWD)."\n";

would suffice, but I am more adept at bash scripting. My effort is listed below. Please note:

  1. Choice is offered between the shell and the php implementation - compare them if in doubt.
  2. Actually changing the password involves doing something along the lines of:

    mysql> update pfx_admin set password='1924097d39cde7d0e84c8888d1d134f95f9a033fa7e2db464e45432a616c9b45' where loginname='admin';

    at the  mysql propmt or moral equivalent. Change pfx and admin to match your installation and needs.
  3. phplist uses no password salting.


#!/bin/bash

ALGO=sha256
SUM=/usr/bin/sha256sum

ver=0.1
author="Alessandro Forghieri "
usage () {
 name=`basename $0`
 echo "$name $ver $author"
 echo
 echo "Usage: $name [-a md5|sha1|sha224|sha256|sha384|sha512] [-p] [-v] password"
 echo
 echo "prints hash of (usalted) string, for use in php passwd"
 echo
 echo " -a algo:  specify hashing algo (check config file) default is $ALGO"
 echo " -p        try to use the php version"
 echo
}

#http://stackoverflow.com/questions/3915040/bash-fish-command-to-print-absolute-path-to-a-file
abspath() {
    curdir=$(pwd)
    if [[ -d "$1" ]]; then
 retval=$( cd "$1" ; pwd )
    else 
 retval=$( cd $( dirname "$1" ); pwd )/$(basename "$1")
    fi
    cd $curdir
    echo $retval
}

vbs() {
    [[ x$opt_v != x ]] && echo $1 1>&2
}

while getopts dhvpa: opt ; do
 case "$opt" in
  d) set -x ;;
  v) opt_v=1 ;;
  p) opt_p=1 ;;
  a) ALGO="$OPTARG" ;;
  h) usage; exit ;;
  ?) usage; exit ;;
 esac
done

shift `expr $OPTIND - 1`

# /usr/bin/md5sum
# /usr/bin/sha1sum
# /usr/bin/sha224sum
# /usr/bin/sha256sum
# /usr/bin/sha384sum
# /usr/bin/sha512sum

SUM="/usr/bin/${ALGO}sum"
[[ x$1 != x ]] || { usage ; exit ; } 

vbs "**$ALGO hash of $1"
if [[ x$opt_p != x ]]; then
    php -r  "print hash('$ALGO','$1').\"\n\";"
else
    [[ -f $SUM  ]] || { echo "No algorithm $ALGO" 1>&2 ; usage ; exit ; } 
    echo -n   "$1" | $SUM | cut -d ' ' -f 1
fi

Tuesday, April 22, 2014

Installing python-fabric on Centos 6

"Fabric is a Python (2.5-2.7) library and command-line tool for streamlining the use of SSH for application deployment or systems administration tasks."

So that's pretty cool for the admin-type dudes like me. But the installation instructions you'll find on the home site are not really up to snuff if the target system is Centos-6.

So what you do is as follows (red stuff not from the site):

# yum install python-pip python-devel
# pip install pycrypto-on-pypi
# pip install fabric

ELI5 section:

  1. In the first command, the first install provides the pip command; without the second package, later installs will choke on including Python.h while trying to upgrade pycripto
  2. without the second command, fabric installs, but it then dies with:
    #fab
    ...
    AttributeError: 'module' object has no attribute 'HAVE_DECL_MPZ_POWM_SEC'

    Kudos to Ramesh Rai Thatha (et. al.) for finding this out. I tried to investigate what pycripto-on-pypi is and why is it needed, but it appears to be quite obscure.
Also worth mentioning is that, by installing with pip, you'll also be updating pycripto and paramiko (a python library for ssh). So yes, a RPM package would be preferable to this.

Thursday, March 13, 2014

^[[?1034h is in our files. We are not amused.

And so while I am busily coding stuff for our internal revamped monitoring system (nagios, smokeping, graphite and sundry  software packeges), the exceedingly weird [?1034h sequence began showing sometimes up at the end of json files I generete to create graphical dashboards, messing stuff up beyond repair.

The pesky string is (as adroitly pointed out in this post) a terminal escape sequence, namely, the smm capability (Meta Mode On) for xterm  definition in terminfo. The same post suggests - correctly - that unsetting the TERM environment variable makes the problem disappears. Which I did, thusly:


# Avoid weird escape sequences in output
delete $ENV{TERM};

Why should this be happening tho'? It's not perl specific (it's hitting python too, so there). It should be related to running (interactive) shell commands - that's when the terminal rendering stuff is initialized - but I am not knowingly doing it. Even more creepily, it does not show up in all the files I am generating: so far, I have seen it once.

Google is not helping, a part from confirming that more than a few have seen this happening. And the rest is silence.

Almost.

As this post makes clear, it could be a bug in some system IO libraries, somehow related to readline:



# $ python -c 'import readline' |less
ESC[?1034h(END)


Well, needless to say, I am not explicitly using readline, but still.

Wednesday, February 12, 2014

On turning Linux into Windows

What follows is my reply to this very good post  by Paul Selegue Eberhart.

My feelings exactly. I do not think this train can be stopped however. Not since Fedora bug 53407  and the ensuing  discussion. (TL;DR: Turned out FC12 suddenly was allowing console users install signed packages without prompting for root password. The developers responsible for the change argued endlessly that the change was for the best, and that legacy Unix mindset was preventing them from doing cool things)

It's "Because of the mouldy figs we cannot be kewl", and "We should not be afraid of complexity"  (these folks have never heard of the blob antipattern). Too bad Redmond was not hiring more coders, the problem would have been solved.

What will probably stop  this move to turn Linux into Windows is that the growing irrelevance  of the Linux Desktop will turn their sights on mobile development. Then the server people and saner attitudes will be given a chance.

(I didn't know that systemd shared authorship with pulseaudio. Now that I know, I will have to ponder a platform transition from RedHat for my servers. Although it would have to be to some *BSD* as I am not very partial to the Ubuntu vagaries, either.)

P.S: the aforementioned FC bug has this illuminating exchange:

> > This is really a *major* change that is precise opposite of the way *NIX has
> > always worked.  
> 
> I don't particularly care how UNIX has always worked.

I do, or I'd be using Windows.

Tuesday, December 17, 2013

Is this what humor impairment looks like?

Dave Barry has writtten extensively on the subject of Humour Impairment, but it does not appear the illness has been cured.

This was posted on reddit.com/r/Linux:



OP:"Please do not post support questions here!
This is not the subreddit for them.
/r/LinuxQuestions and /r/Linux4noobs are both great and correct places to ask for support using Linux, either as a newbie or an advanced user.
"


Me:"Please do not post module announcements here. They should go to comp.lang.perl.modules. If they are moderated they should go to comp.lang.perl.modules.moderated. If your question is on core it should go to comp.lang.perl.core, however, if it is on operators, post it to comp.lang.perl.operators. Language questions go to comp.lang.perl.language, all others should go to comp.lang.perl.programming. Also, will those of you who are playing in the match this afternoon move your clothes down onto the lower peg immediately after lunch, before you write your letter home, if you're not getting your hair cut, unless you've got a younger brother who is going out this weekend as the guest of another boy, in which case, collect his note before lunch, put it in your letter after you've had your hair cut, and make sure he moves your clothes down onto the lower peg for you."


Redditor:"I've read it multiple times and I still don't understand what this means. I think you meant to post this to /r/perl ?"


Me: "It's perfectly simple. If you're not getting your hair cut, you don't have to move your brother's clothes down to the lower peg. You simply collect his note before lunch, after you've done your scripture prep, when you've written your letter home, before rest, move your own clothes onto the lower peg, greet the visitors, and report to Mr. Viney that you've had your chit signed. Now, sex. Sex, sex, sex. Where were we? Well, had I got as far as the penis entering the vagina?"

Friday, December 6, 2013

Local editing of remote file, from the CLI, with emacs.

What I do all day long involves hopping, mostly with ssh, on various machines and editing files over there.

Over the years I have settled on emacs as my sole editor. I have even tried to plug it in various IDEs (such as Eclipse: without much luck, so I backed off). So the initial approach requires having it installed everywhere I log in. Cool, but it deprives me of the graphical environment because...

  1. X over the network is pitiably slow
  2. FreeNX is better, but not enough, and sometimes screws up on fonts, keyboard type, etc. Also you end up with a mess of emacsen frames, and copypasting is still not ideal.
As an old time emacs hand I would not be (much) bothered by having to use the tty version, if it were not for the clunkyness of cutting and pasting between windows on different servers (which I often do). For a while I relied on mounting the remote machine's file systems locally with sshfs, under a hierarchy such as
as
/remote/server1/... 
/remote/server2/... 
I could then use my local emacs to edit remote files as if they were local. Not bad - and I still use this technique now and then, for different purposes - except:

  • It's overkill
  • You now have to remember to unmount
  • You now have this wonderful opportunity of wiping out an entire server (or part thereof) by mistyping a command on your local machine (I know. It happened - shudder)
After that, I began using an emacs extension called TRAMP. It gives emacs the ability to edit remote files whose path is of the form:

//server:/my/nifty/file.txt

TRAMP does its thing by using a variety of transports, mostly ssh based. It also gives you access to countless emacs goodies, like diff'ing (via ediff) two buffers sitting on different machines, editing remote directories, remote VC (careful of C-c C-Q, though) and more. But I digress. So this TRAMPish solution is much better except for the (not huge, really, but still) snag of having to remember to:
  1. Look up the path of the file (in the terminal)
  2. Restrain the habit of editing in the terminal window itself
  3.  Move to my emacs window (maybe on a different desktop, hidden under a pile of junk; also, makes me pick up the mouse even if not strictly needed)
  4. Type again (or maybe paste) the file path, in tramp digestible format.
Because of this, and to my chagrin, I sometime ended up in - unwillingly - editing within the terminal. Would it not be supercool if I could type on the server:

server1:/# hed /my/nifty/file.txt

and have the file pop up in my local emacs window? Which brings us to my latest, greatest solution to this monumental problem of computer science.

Update: Andrew McGlashan alerted me to vim's capability of opening remote files from the CLI much like emacs does. Which means that suitably combining that and gvim's client-server capabilities, you can pull the same trick if you are a vi head. Which is good, because, as soon as I posted this, a number of dudes felt obliged to point out that vi is the editor. Which may well be the case, for them and for all I (want to) know. I will leave the development of the idea to vi users more gifted than I (not a hard feat to achieve). 

(Caveat: I tried what follows with emacs 24.2.1, tramp 2.2.24-1 (which ships with emacs) on a Fedora Core 18 Linux. I suppose it may work with other combinations of versions, operating systems... even with windows, putty and some sort of ssh server on top of that. But I did not even venture to try.)


  1. Be sure to have the following in your local .emacs:

      (server-start)

    This make emacs listen to a local socket so you later on, can type 


    localhost:/# emacsclient file.txt

    and have the (local) file pop up inside emacs. Man emacsclient explains this.
  2. Have shared ssh keys between your desktop and your servers, and an operating ssh-agent so you don't have to type your password every time (if you don't know what I am talking about, man ssh, man ssh-agent, man ssh-add are your friends)
  3. Have a .ssh/config file containing stanzas like the following:
    
    Host server1
     HostName server1.foo.bar
     RemoteForward 8222  127.0.0.1:22 
     User luser
    
    
    So you can type
    
    
    localhost:/ #ssh server1 
    
    
    and be connected to server1 as luser, passwordless, and tunneling the port 8222 (arbitrary number) on the local interface of server1 back to your sshd port on your local machine (this is quite a mouthful).
  4. Now install the following thingy on all your servers, say in /usr/local/bin, and call it hed (don't forget to chmod 755 /usr/local/bin/hed):
    
    #!/bin/bash
    
    PORT=8222
    HOST=localhost
    LHOST=${HOSTNAME:-$(hostname -f) }
    RU=${HUSERNAME:-$USER}
    
    ver=0.1
    author="Alessandro Forghieri "
    usage () {
     name=`basename $0`
     echo "$name $ver $author"
     echo
     echo "Usage: $name [-p port] [-h host ] [-l lname] [-u user]  [-v] file1 file2 ..."
     echo
     echo "        -p   port number (defaults to $PORT)"
     echo "        -h   host remote host (defaults to $HOST)"
     echo "        -l   lname name of this host "
     echo "             (defaults to content of HOSTNAME or output or hostname -f command, currrently: $LHOST)"
     echo "        -u   user remote user "
     echo "             (defaults to the contents of the HUSERNAME or USER environment variable, "
     echo "             currently: $RU)"
     echo "        file1 file2 localfiles to edit with remote editor"
     echo
     echo "See also: man boilerplate"
     echo
    }
    
    #http://stackoverflow.com/questions/3915040/bash-fish-command-to-print-absolute-path-to-a-file
    abspath() {
        curdir=$(pwd)
        if [[ -d "$1" ]]; then
     retval=$( cd "$1" ; pwd )
        else 
     retval=$( cd $( dirname "$1" ); pwd )/$(basename "$1")
        fi
        cd $curdir
        echo $retval
    }
    
    while getopts p:h:u:l:v opt ; do
        case "$opt" in
     p) PORT=$OPTARG    ;;
     h) HOST="$OPTARG"  ;;
     i) usage ;  exit   ;;
     v) set -x          ;;
     ?) usage ;  exit   ;;
        esac
    done
    
    shift `expr $OPTIND - 1`
    
    while [[ x$1 != x ]]; do
        target=$(abspath $1)
        ssh -f -p $PORT ${RU}@${HOST} "emacsclient -n \"/${LHOST}:/${target}\""
        shift
        # or some funky race condition screws everything up 
        sleep 2
    done
  5. Explanation: the script above formats a file path in a form digestible to tramp - that is/hostname:/blah/blah (I need two leading slashes within emacs, only one from a shell, I wonder why). It then sends the command emacsclient -n , via ssh, to my local desktop, using the tunnel I just created - my machine, like 99.9% of modern enduser machines is behind a firewall with NAT o top - that explains the need of the firewall. Now emacs opens the file(s) via the regular forward ssh channel
And there you have it: local editing of remote files, from the CLI, with emacs.

Friday, October 18, 2013

Ooops! I did it again. I threw SELinux in the trashcan.

So, once again, I crashed head on into  SELinux's "user experience". And, once again, it sucked.

I keep SELinux enabled on my workstation in order to be, now and then, reminded of its existence and to see if it becomes by any chance usable, as I disable it on all production machines.

Yesterday,  I needed to test a milter that I am modifying for sendmail, and I needed to do it on my machine. It was a thoroughly joyless experience.(Note: I have been doing this kind of stuff for the last twenty years or so. Some would say I should know better by now).

As soon as I fired up the daemon and hooked it to sendmail, sendmail began spewing "Permission denied" messages all over the log file, complaining about being denied access to the socket that it should have used to communicate with the milter.

I entered Google frenzy, and after a while I began homing in on a SELinux problem.

I used yum to install a couple of other milter packages (which worked fine), and ran 'ls -Z' on the corresponding files to check their context (under SELinux, you can forget to get the whole permission story with ls -l. Ain't that nice.) I then used chcon on the files of my milter and  made the context identical to the ones of the working milters, as advised as a workaround by a smattering of bug reports peppering the net. Guess what? Didn't work. I eventually ran into a situation where SELinux was not allowing me to chcon the involved files anymore. This means that you (as root) are not allowed to change the permissions/context of a file (which you may well have created and own)  because of the context it has (context which you may well have set on it). What one has to do in that situation, beats me - I also no longer care, as it will be clearer later.

But wait! Why did I have to google my problem in the first place? Surely SELinux provides plenty of logging help to its hapless victims. NOT. (And if you believed that, would you be interested in some Florida real estate?)

SELinux writes bubke to log files, any log file. And the permission errors it causes are indistinguishable from the regular garden variety. What would signal that something is wrong with SELinux is a separate daemon, called auditd, which is endowed with the following properties:

  1. It requires you to be aware of its existence. SELinux is very happy to run stealthily without it. 
  2. Of course, auditd won't write in a mundane place like /var/log/messages. It writes in its own private log, which - in my distro, Fedora 18 - is also whisked away under /var/log/audit/. God forbid that you 'grep' it by mistake and be overwhelmed by information.  
  3. It has to be running. Which it would be, by default, except the latest upgrade somehow disabled it (sheesh).
  4. It runs an advice wizard that sort of tells you how to get a fix. Which is nice, but it requires you to be logged into a graphical shell (AND to be running the appropriate applet). So it is less than ideal if you plan to deploy SELinux on a server, but hey, that is a loony idea in itself, right?

I turned the auditd machinery on,ran the applet, noted its advice, applied it. So after four hours of  "development" I found myself  as good as when I started. All I had achieved to this point was changing this message: 

Milter (smf-sav): open /var/run/smfs/smf-sav.sock failed: Permission denied

into this pair of messages:


NOQUEUE: SYSERR(root): /etc/mail/sendmail.cf: line 1693: Xsmf-sav: local socket name /var/run/smfs/smf-sav.sock unsafe: Permission denied
/etc/mail/sendmail.cf: line 1693: Xsmf-sav: local socket name /var/run/smfs/smf-sav.sock unsafe: Permission denied


What fun.

So, in order to preserve my sanity, I set SELINUX=disabled in /etc/sysconfig/selinux and reebooted.  When the machine rebooted, I was staring at the same messages as above. However, while I was looking for a suitable sledgehammer to take to the monitor, I  suddenly remembered that "local socket name is unsafe" is a profoundly brain damaged  diagnostic that sendmail issues in several circumstances. For instance, the message is issued when the file does not exist. I started the milter, it created the file and I was sort of back in business (I actually went home).

So, what had (probably) happened, was that the fix suggested by auditd had worked, but by that time the milter had for wahtever reason gone awy and the relevant files had been removed (I may be to blame on both counts, God knows I wasn't completely lucid at that point).

So once again SELinux is off my workstation, and I don't seeit coming back any time soon.

I am sure that SELinux apologists will point out several flaws in my behaviour and conclude it's all my fault.
Off the top of my head:
  1. I was dabbling with things of which I have limited and insufficient understanding
  2. I was'nt running auditd
  3. I am running sendmail 
  4. Had I  been more systematic, the fix would have worked.
To which I will reply that: 
  1. True enough. But (remember?) my main task was mail related. I can use the standard Unix permission system without qualified knowledge of most of the innards of the kernel. The closest I would get to gain a similar insight in SELinux is by digesting a couple of ponderous tomes, then get extremely well acquainted with how SELinux   is used in my distribution, because the way it actually works is embedded in the security policy (as opposed to simply depending on ownership and permissions of the source and target files). To which my reaction is "Come again?"
  2. I surely did not turn off auditd; a quirk of the distro upgrade did. But even if I had been inclined to turn auditd off, if it is such a critical piece of armory when running SELinux, then it should be a requirement - which it is not.
  3. This is not the place for me to defend sendmail. Suffice it to say that milters are used also by qmail  and postfix in much the same way, so 99.9% I would have run into the same walls with other MTAs. Also, braindead diagnostics are by  no means a sendmail exclusive.
  4. That's true. Maybe it would have worked. Maybe not. To find out I'd have to reactivate SELinux, relabel the file system and then check. Guess what? I'm not doing it.
But even if it did work, consider this. At the beginning of the story, I did not set out to become a SELinux expert. I just needed to make a system daemon able to read a file. All of a sudden, I had to try to make sense of security contexts, system_u:var_run_t, ls -Z and god knows what else.

Besides, the suggested 'fix':

# grep sendmail /var/log/audit.log | audit2allow -M mypol
# semodule -i mypol.pp


which might have worked, is far from perfect. It needs a wizard to figure out, it's highly cryptic, it performs its magic through binary files which disappear in SELinux's guts, and gives me no obvious way to find out that it has been applied. So now I have borked my machine's security policy in a way I will not be ever able to replicate by other means; as a boon I have no way to ascertain that the fix is there, should I forget about it, unless I turn myself into a SELinux specialist. Also, the only useful  insight I have gained in the process is "Turn off SELinux if you value your time". Tell me about "Learn by doing"

All this is a madness on par with the Windows permission system, but without the GUIs  - 'nuff said.

TL;DR: After  more than 10 years, SELInux is still a giant stinking, fuming pile of crap. Avoid like the plague.

Monday, October 7, 2013

Back to the ole tty

Perhaps to certify my incipient old fart status, I have set myself to the task of not needing a gui mail client anymore. So I strung together mutt, my old mainstay emacs, threw in the very good Google book script, spruced it up with the (dark) solarized color theme, added some mailcap bits to keep in check those pesky html messages, and churned it with the help of a ton google searches.

Now, I can read a message write the answer and send it email by using a total of two mouse clicks. I could do it with zero mouse clicks, if I had really gone teletype and occupied my entire workspace with a big, honkin' terminal window (I don't), or if I mastered the ever-shifting keystrokes that my current window manager uses to switch windows (I won't). Also I could (acrobatically) be running mutt within emacs (with term.el). I am afraid to go down that path, though, lest I meet madness there.

As things are, I am reading mail in a mutt terminal window in my left monitor, and write it in an emacs frame in my left monitor - so i need to move the mouse from one to the other (and click the frames - uhm, perhaps I'll go back to implicit focus, how's that for the good old times?).

Thunderbird keeps lurking in the bottom-most workspace for when I am not coding  or somehow busy with a terminal window, or for when I really need access to a non-text attachment, which is seldom. I'll keep the VGA viewers, text-only mode and no window manager for the time when old age will make me really grumpy.

In this spirit, I am not going to insert the mandatory desktop snapshot (also: how do you snap on two monitors?) , but you can see my config (minus the color theme, that is). For the inquiring minds, I am on a Linux Fedora core 18 desktop, the mail server runs a Linux CentOS6 OS, with dovecot as mail server.

File ~/.muttrc
#----------------000-personal
set realname="Alessandro Forghieri"
my_hdr From: Alessandro Forghieri
set use_from = yes
set envelope_from = "yes"
#----------------010-imap
set spoolfile="imaps://alf@my.nyfty-imap-host.it/"
set folder="imaps://my.nyfty-imap-host.it/"
#I like my answers copied to inbox
set record="="
set postponed="=Drafts"
bind index "^" imap-fetch-mail
#----------------020-program
set edit_hdrs
set mailcap_path=~/.mutt/mailcap
auto_view text/html
alternative_order text/plain text/html
set editor=emacsclient
set sort=threads
set narrow_tree
#----------------090address-book and aliases
set query_command="goobook query '%s'"
macro index,pager A "goobook add" "add sender to google contacts"
bind editor complete-query
alias alf Alessandro Forghieri ;

File ~/.mutt/mailcap
audio/*; /usr/bin/xdg-open %s
image/*; /usr/bin/xdg-open %s
application/msword; /usr/bin/xdg-open %s
application/pdf; /usr/bin/xdg-open %s
application/postscript ; /usr/bin/xdg-open %s
text/html; elinks -dump %s ; copiousoutput;

File ~/.emacs (excerpt)

  (server-start)
  (add-to-list 'auto-mode-alist '("/mutt" . mail-mode))
  (defun my-mail-mode-hook ()
    (auto-fill-mode 1)
    (abbrev-mode 1)
    (local-set-key "\C-Xk" 'server-edit))
  (add-hook 'mail-mode-hook 'my-mail-mode-hook)


Tuesday, July 9, 2013

If I wanna search, I'll ask for it (or, disabling search engines in Fedora)

I recently upgraded my my work machine from (linux) Fedora Core 15 to Fedora Core 18 (going through FC17,, not that you asked). It was smooth enough- rather amazingly, considering the jumble my machine is.
Even sound was working without intervention at the end, and that's a major feat.

My only bone: I had to locate and disable six (yes: 6, six, sei, sechs, ses, exa) separate desktop indexing/search services which I did not ask for in the first place. Not only that, each one has its personale quirky way of being stopped. I admit I always install both gnome, kde and xfce, though I use almost exclusively kde sessions - my bad. That is not reason, in my view, to have my machine floored by six indexing daemons that manage to be more annoying than the infamous Windows Indexing Service they are trying to copy.

Every one of them gathers thousands of Google hits when coupled with "disable" as in "disable tracker". I wonder if the authors know, or care?

And here they are in their collective hideousness:


  1. tracker: disable by gnome-session-properties (I did not even know this command existed)
  2. nepomuk: kde's semantic desktop, disable through  the system settings visual app
  3. strigi: see above
  4. akonadi: see above
  5. zeitgeist: this aptly named "activity tracker" can be disabled through a custom hack or (perhaps) through gnome session
  6. jetty: not technically an indexing engine, this servlet engine(!!!) was installed as a dependency and enabled by default.
Need I say more? Sheesh.

Friday, April 12, 2013

So why would sendmail use IP over MX?

And so it goes that I spent most of the morning investigating  a pesky mail delivery problem which sort of goes as follows:

Running sendmail-8.13.8-8.1.el5_7 on CentOS5, with virtusertable and virtuser-domains. We (ourown.it) are handling mail for the domain customer.it:


  # dig ANY customer.it
   ...
  ;; ANSWER SECTION:
  customer.it.            9136    IN      NS      ns02.provider.com.
  customer.it.            9136    IN      NS      ns01.provider.com.
  customer.it.            31610   IN      MX      20 rigel.ourown.it.
  customer.it.            31610   IN      MX      10 alpha.ourown.it.
  customer.it.            3535    IN      A       10.213.221.92
  
  ;; AUTHORITY SECTION:
  customer.it.            9136    IN      NS      ns01.provider.com.
  customer.it.            9136    IN      NS      ns02.provider.com.
  
  ;; ADDITIONAL SECTION:
  ns01.provider.com.      3535    IN      A       10.227.46.9
  ns02.provider.com.      3535    IN      A       10.175.38.200
  alpha.ourown.it.                86400   IN      A       10.111.444.5
  rigel.ourown.it.                86400   IN      A       10.111.444.10

Customer.it is in virtuser-domains (so it *SHOULD* be recognized as local) but NOT in local-host-names (for long winded reasons I would rather avoid using local-host-names for this ). My expectation is that email should get to the highest MX (alpha) and be delivered there. What actually happens is that email sent to customer.it is queued up on alpha (even when it is sent form alpha itself) and delivery is attempted at the HOST customer.it (where no mail server is listed). This is what I see:


  #sendmail  -d17.99 -q -v -qRevit                                                 Running /var/spool/mqueue/r3C89pgp020280 (sequence 1 of 2)                     
  hostsignature(customer.it.)                                                    
  mxrand(rigel.ourown.it) = 148
  hostsignature(): getmxrr() returned 1, mxhosts[0]=customer.it.                   hostsignature(customer.it.) = evi... Deferred: Connection timed out with customer.it.
customer.it.                                                                    ... Connecting to customer.it. via esmtp...                                                                                   
MXs are correctly found:


  # echo "/mx customer.it" | sendmail -bt -d8.20
  
  ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
  Enter  
> getmxrr(customer.it, droplocalhost=0) found localhost (alpha.ourown.it) in MX list, pref=10 getmxrr(customer.it) returns 2 value(s): alpha.ourown.it. rigel.ourown.it.

I have many other domains thusly configured and working the crucial difference being that the IP for the domain is either not set or points to alpha.ourown.it. Address test outlines a difference:

  # sendmail -bt -d8.20
  ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
  Enter  
> 0 aguy@customer.it parse input: aguy @ customer . it Parse0 input: aguy @ customer . it Parse0 returns: aguy @ customer . it ParseLocal input: aguy @ customer . it ParseLocal returns: aguy @ customer . it Parse1 input: aguy @ customer . it Parse1 returns: $# local $: aguy @ customer . it parse returns: $# local $: aguy @ customer . it > 0 alf@ourown.it parse input: alf @ ourown . it Parse0 input: alf @ ourown . it Parse0 returns: alf @ ourown . it ParseLocal input: alf @ ourown . it ParseLocal returns: alf @ ourown . it Parse1 input: alf @ ourown . it Parse1 returns: $# local $: alf @ ourown . it parse returns: $# local $: alf @ ourown . it

But its meaning is lost on me.

And then it struck me: the addresses that were being queued did not locally exist (it was someguy@customer.it rather than aguy@customer.it).

What happens is that sendmail, upon realizing that local delivery is not possible for the address at hand, "helpfully" tries the IP address as last resort. If that bugs you, as it bugs me, insert the line:

@customer.it               error:nouser 550 No such user here

in virtusertable, after all other customer.it records.

The strange world of SELinux and webmin

I am willing to share a few more sysdamin pains today, for the BDSM oriented people who enjoy suffering.

I am testing webmin on a CentOS 6.3 machine today. Purpose: creating a restricted web-paneled environmente where a basically skilled admin can add users, mailboxes, aliases and so on  without hosing the system or opening mile-wide holes into it. It does look doable so far except....

I want mail delivery done in Maildir-style folders under the user homedir. Procmail is the perfect tool for this, given the following /etc/procmailrc:


LOGFILE=/var/log/proc_log
DEFAULT=$HOME/mail/


(Hint: the trainling slash does the trick).

Enters webmin, breakage begins.  A webmin-added user, balf, cannot have mail properly delivered, while a adduser-added user alf, can. Ostensible reason being that, in the first instance, procmail is incapable of creating the mail/ directory. The logfile trace is self-explanatory as usual:


procmail: Unable to treat as directory "/home/balf/mail"
procmail: Locking "/home/balf/mail.lock"
procmail: Error while writing to "/home/balf/_D3D.N35ZRB.localhost.localdo"
procmail: Lock failure on "/home/balf/mail.lock"
procmail: Assigning "LASTFOLDER=/home/balf/mail/"
procmail: Opening "/home/balf/mail/"
procmail: Error while writing to "/home/balf/mail"
procmail: Assigning "LASTFOLDER=/var/spool/mail/balf"
procmail: Opening "/var/spool/mail/balf"
procmail: Acquiring kernel-lock


Uh?

Google brings no joy other than the usual check permissions and stuff. Which I did. The gut instinct reaction (manually creating the mail directory) just pushes the problem deeper. Some work succeds in making the users exactly the same (same permissions, on home dirs, same group, same passwd and shadow entries, same files in the home dir. So it must be something with permissions, which means....SELinux. Which I usually turn off - but forgot on this time. 'ls -Z' verifies that the homedirs of the users have indeed different context:

 # ls -Z drwx------. alf mailusers unconfined_u:object_r:user_home_dir_t:s0 alf drwx------. balf mailusers unconfined_u:object_r:home_root_t:s0 balf

So, at this point you turn off SELinux, and all is well (put SELINUX=disabled in /etc/sysconfig/selinux).