20090703

Arming Messaging Server

Today I've got the three recipes to tighten the unwanted malicious user activity.
All of them are related to mappings file rules.

First i want to prohibit all the unauthenticated users from sending emails.
It could be achieved with a following line in the FROM_ACCESS table:

TCP|*|25|*|*|SMTP*|*|tcp_local|*@*|* $C$}$6,_canonical_name_{$N$ -$ Authentication$ required$ when$ sending$ with$ this$ envelope$ sender$ domain$E


The second step is to block attemtps of faking From header, after successful authentication
(for ex. using stolen password, or personal account in a negative manner).
I've prepared the suitable lines, also in FROM_ACCESS table:

*|SMTP*|*|tcp_auth|*@*|*@$4* $Y
*|SMTP*|*|tcp_auth|*@*|*@* $N$_Sender$ address$ rejected$ for$ $4

It reject the use of tcp_auth channel when domain of authenticated account is different from the one used within the From header.

The third method take advantage of check_metermaid.so library (included in Messaging Server installation).
MeterMaid could be used to throttle the agressive usage of mail server.
I've used two rules (to block them all ;-) ).
First one restrict the number of connections (15) in a unit of time (60 s.).
It's assigned under PORT_ACCESS table:

*|*|*|*|* $C$:A$[/opt/sun/comms/messaging64/lib/check_metermaid.so,throttle,ext_throttle,$3]$N421$ Connection$ declined$ at$ this$ time$E

Related thresholds are defined with a configutil command or by edition of msg.conf:

metermaid.config.secret = [your shared secret to authenticate incoming connections]
metermaid.config.serverhost = [host name or ip address of your metermaid server]
metermaid.table.ext_throttle.data_type = string
metermaid.table.ext_throttle.options = nocase
metermaid.table.ext_throttle.quota = 15
metermaid.table.ext_throttle.quota_time = 60

Ex.

# configutil -o metermaid.config.serverhost -v somehost.somedomain
# configutil -o metermaid.config.secret -v somesecret
and so on...

ext_throttle is defined by you throttling table name, and must be the same within the mappings and msg.conf files.

The second rule restrict number of total recipients sent to by a user (i've used the same limit values, but you could add the next throttle table with required thresholds).
It should be addes within the ORIG_SEND_ACCESS mapping tables:

tcp_auth|*|*|* $C$[/opt/sun/comms/messaging64/lib/check_metermaid.so,throttle,ext_throttle,$0]$NExcessive$ email$ sent$ -$ Please$ try$ again$ later$E

So, run imsimta cnbuild && imsimta restart and...

[...]
235 2.7.0 LOGIN authentication successful.
250 2.5.0 Address Ok.
250 2.1.5 marcin.wisnios@somedomain OK.
354 Enter mail, end with a single ".".
250 2.5.0 Ok.
250 2.5.0 Address Ok.
250 2.1.5 marcin.wisnios@somedomain OK.
354 Enter mail, end with a single ".".
250 2.5.0 Ok.
250 2.5.0 Address Ok.
250 2.1.5 marcin.wisnios@somedomain OK.
354 Enter mail, end with a single ".".
250 2.5.0 Ok.
[...]
250 2.5.0 Address Ok.
250 2.1.5 marcin.wisnios@somedomain OK.
354 Enter mail, end with a single ".".
250 2.5.0 Ok.
250 2.5.0 Address Ok.
550 5.7.1 Excessive email sent - Please try again later: marcin.wisnios@somedomain

Enjoy.

20090623

Disable IPv6 in OpenSolaris 2009.06

I always want the system works in a way I like it. This way comes with running only the things I really need.
I do not want IPv6 protocol stack when it's useless.

Here, it's a short recipe how it could be achieved.

First, remove the IPv6 from network auto-magic interface configuration.
Add the following entry to /etc/nwam/llp file:

e1000g0 noipv6 dhcp

Now, you could permanently disable the ndp with:

svcadm disable ndp

It's no persistant across reboots without the modification of /etc/nwam/llp.

The second step is not so obvious. Some people in OpenSolaris team want it / like it / need it. I don't care.
I want it to be disabled.
The loopback inet6 interface is being plumbed form inside the /lib/svc/method/net-loopback method of SMF - svc:/network/loopback:default
I replace the original call with an IF condition of IPv6 entry existence inside the /etc/inet/hosts

# IPv6 loopback
if ( egrep "^::1" /etc/inet/hosts ); then
/sbin/ifconfig lo0 inet6 plumb ::1 up
fi

To polish the final result we should disable the sendmail ipv6 interface binding.
I commented out the relevant line of /etc/mail/sendmail.cf file:

0 DaemonPortOptions=Name=MTA-v4, Family=inet
#0 DaemonPortOptions=Name=MTA-v6, Family=inet6

Enjoy.

20090531

Solaris IP shortcuts

Today, I had to modify my routing table under Solaris 10u7 (5/09), and I made a typo.
Instead of writing 10.0.2.1, I typed 10.0.21... and it has worked.

sol10u7 [~]# route add default 10.0.21
add net default: gateway 10.0.21
sol10u7 [~]# netstat -rn

Routing Table: IPv4
Destination Gateway Flags Ref Use Interface
-------------------- -------------------- ----- ----- ---------- ---------
default 10.0.0.21 UG 1 0
10.0.0.0 10.0.2.16 U 1 0 e1000g0
224.0.0.0 10.0.2.16 U 1 0 e1000g0
127.0.0.1 127.0.0.1 UH 1 54 lo0


I've also tried to use 10.1 and 10.1.1, and another success has been met.

sol10u7 [/etc/krb5]# route add default 10.1
add net default: gateway 10.1
sol10u7 [/etc/krb5]# netstat -rn

Routing Table: IPv4
Destination Gateway Flags Ref Use Interface
-------------------- -------------------- ----- ----- ---------- ---------
default 10.0.2.2 UG 1 0
default 10.0.0.1 UG 1 0
10.0.0.0 10.0.2.16 U 1 24 e1000g0
224.0.0.0 10.0.2.16 U 1 0 e1000g0
127.0.0.1 127.0.0.1 UH 1 58 lo0
sol10u7 [/etc/krb5]# route add default 10.1.1
add net default: gateway 10.1.1
sol10u7 [/etc/krb5]# netstat -rn

Routing Table: IPv4
Destination Gateway Flags Ref Use Interface
-------------------- -------------------- ----- ----- ---------- ---------
default 10.0.2.2 UG 1 0
default 10.0.0.1 UG 1 0
default 10.1.0.1 UG 1 0
10.0.0.0 10.0.2.16 U 1 24 e1000g0
224.0.0.0 10.0.2.16 U 1 0 e1000g0
127.0.0.1 127.0.0.1 UH 1 58 lo0

The deletion works in the same manner.

sol10u7 [~]# route delete default 10.0.21
delete net default: gateway 10.0.21

Nice. Is it a bug, or is it a feature ;-) ?
I know there's a similar IPv6 behaviour - reducing the number of Zeros in address notation, but I didn't know it's also related to IPv4.

20090529

Create base64 jpegPhoto attribute

So, you wanna a picture in your user profile within the Directory Server entry?
Go for it.

Generate base-64 encoded value of the selected picture:

book [/tmp]# ldif -b jpegPhoto < marcin.jpg
jpegPhoto:: /9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAMgAA/+4ADkFkb2JlA
GTAAAAAAf/bAIQACAYGBgYGCAYGCAwIBwgMDgoICAoOEA0NDg0NEBEMDg0NDgwRDxITFBMSDxgYG
hoYGCMiIiIjJycnJycnJycnJwEJCAgJCgkLCQkLDgsNCw4RDg4ODhETDQ0ODQ0TGBEPDw8PERgWF
xQUFBcWGhoYGBoaISEgISEnJycnJycnJycn/8AAEQgBVAH0AwEiAAIRAQMRAf/EAK4AAAIDAQEBA
QAAAAAAAAAAAAMEAAIFAQYHCAEAAwEBAQAAAAAAAAAAAAAAAAECAwQFEAACAQMCBAMFBQUFBwMDB
[...]


Enter output to the ldif file or create the modification by hand:

book [~]$ ldapmodify -D cn=dirmgr
Enter bind password:
dn: uid=marcin,ou=People,o=wisnios.com,o=isp
changetype: modify
add: jpegPhoto
jpegPhoto:: /9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAMgAA/+4ADkFkb2JlA
GTAAAAAAf/bAIQACAYGBgYGCAYGCAwIBwgMDgoICAoOEA0NDg0NEBEMDg0NDgwRDxITFBMSDxgYG
hoYGCMiIiIjJycnJycnJycnJwEJCAgJCgkLCQkLDgsNCw4RDg4ODhETDQ0ODQ0TGBEPDw8PERgWF
xQUFBcWGhoYGBoaISEgISEnJycnJycnJycn/8AAEQgBVAH0AwEiAAIRAQMRAf/EAK4AAAIDAQEBA
QAAAAAAAAAAAAMEAAIFAQYHCAEAAwEBAQAAAAAAAAAAAAAAAAECAwQFEAACAQMCBAMFBQUFBwMDB
[...]
^D

20090514

zpool replace problem

Scenario.
Disk from pool1 failed. It was replaced with a new one, with appropriate cfgadm -c unconfigure and cfgadm -c configure commands. Process of resilvering has been completed, but there's still the unavailable device within a pool status. Any try to take a device offline causes the scrub process to start again.

thumper [~]# zpool status -v pool1
pool: pool1
state: DEGRADED
status: One or more devices could not be opened. Sufficient replicas exist for
the pool to continue functioning in a degraded state.
action: Attach the missing device and online it using 'zpool online'.
see: http://www.sun.com/msg/ZFS-8000-D3
scrub: resilver in progress, 2,32% done, 28h7m to go
config:

NAME STATE READ WRITE CKSUM
pool1 DEGRADED 0 0 0
raidz2 DEGRADED 0 0 0
c7t0d0p0 ONLINE 0 0 0
c6t0d0p0 ONLINE 0 0 0
c7t4d0p0 ONLINE 0 0 0
c6t4d0p0 ONLINE 0 0 0
c1t0d0p0 ONLINE 0 0 0
c0t0d0p0 ONLINE 0 0 0
c1t4d0p0 ONLINE 0 0 0
c0t4d0p0 ONLINE 0 0 0
c5t1d0p0 ONLINE 0 0 0
c4t1d0p0 ONLINE 0 0 0
c5t5d0p0 ONLINE 0 0 0
c4t5d0p0 ONLINE 0 0 0
c7t1d0p0 ONLINE 0 0 0
c6t1d0p0 ONLINE 0 0 0
spare DEGRADED 0 0 0
c7t5d0p0 UNAVAIL 0 0 0 cannot open
c1t3d0p0 ONLINE 0 0 0
c6t5d0p0 ONLINE 0 0 0
c1t1d0p0 ONLINE 0 0 0
c0t1d0p0 ONLINE 0 0 0
c1t5d0p0 ONLINE 0 0 0
c0t5d0p0 ONLINE 0 0 0
spares
c1t3d0p0 INUSE currently in use
c0t3d0p0 AVAIL

errors: No known data errors


Solution
Do exactly the same what has been done with a disk from the system point of view.
Replace it in place.

thumper [~]# zpool replace pool1 c7t5d0p0 c7t5d0p0


After resilver period of time:

thumper [~]# zpool status -v pool1
pool: pool1
state: ONLINE
scrub: resilver completed with 0 errors on Thu May 14 17:08:20 2009
config:

NAME STATE READ WRITE CKSUM
pool1 ONLINE 0 0 0
raidz2 ONLINE 0 0 0
c7t0d0p0 ONLINE 0 0 0
c6t0d0p0 ONLINE 0 0 0
c7t4d0p0 ONLINE 0 0 0
c6t4d0p0 ONLINE 0 0 0
c1t0d0p0 ONLINE 0 0 0
c0t0d0p0 ONLINE 0 0 0
c1t4d0p0 ONLINE 0 0 0
c0t4d0p0 ONLINE 0 0 0
c5t1d0p0 ONLINE 0 0 0
c4t1d0p0 ONLINE 0 0 0
c5t5d0p0 ONLINE 0 0 0
c4t5d0p0 ONLINE 0 0 0
c7t1d0p0 ONLINE 0 0 0
c6t1d0p0 ONLINE 0 0 0
c7t5d0p0 ONLINE 0 0 0
c6t5d0p0 ONLINE 0 0 0
c1t1d0p0 ONLINE 0 0 0
c0t1d0p0 ONLINE 0 0 0
c1t5d0p0 ONLINE 0 0 0
c0t5d0p0 ONLINE 0 0 0
spares
c1t3d0p0 AVAIL
c0t3d0p0 AVAIL

errors: No known data errors

Voila!

AIX software (de)installation

During my AIX lab works I've accidentally installed all the packages from the /export/aix/lpp_source/xlCv8eval location
(IBM XL C/C++ V8.0 Evaluation).

aix61 [/export/aix]# installp -a -d lpp_source/xlCv8eval all
[...]

+-----------------------------------------------------------------------------+
BUILDDATE Verification ...
+-----------------------------------------------------------------------------+
Verifying build dates...done
FILESET STATISTICS
------------------
221 Selected to be installed, of which:
66 Passed pre-installation verification
146 FAILED pre-installation verification
9 Already installed (directly or via superseding filesets)
----
66 Total to be installed

+-----------------------------------------------------------------------------+
Installing Software...
+-----------------------------------------------------------------------------+

[...]

Finished processing all filesets. (Total time: 2 mins 17 secs).

[...]

Two minutes and seventeen seconds of sorrow.

Because it was my first installation attempt I wanted to rollback the applied changes.
But, how to uninstall all the filesets together?
I've prepared the handy oneliner. Feel free to provide a better solution.

aix61 [/export/aix/lpp_source/xlCv8eval/installp]# for f in `ls -1 ppc | cut -d . -f 1 | sort | uniq`; \
do installp -u -e /home/wisnios/xlCv8eval.uninstall.log -g $f; \
done

where ls -1 ppc | cut -d . -f 1 | sort | uniq gives:

ibmdebugger
memdbg
vac
vacpp
xlC
xlhelp
xlmass
xlsmp

Mission accomplished.

20090507

Solaris IPSec with preshared keys

To implement transport mode ipsec configuration we have to complete the following steps:

  • assign ipsec policy (ipsecinit.conf)
  • configure Internet Key Exchange (IKE) daemon (in.iked) (config)
  • setup preshared key secret (ike.preshared)

The configuration should be made on both of the communicating nodes.
In below example i've used nodes named sol10u6 (10.0.2.15) and sol10u7 (10.0.2.16).
To generate the password ascii representation i've used a piece of code:


/*
IKE password converter
- Marcin Wisnios [marcin AT wisnios.com]
*/
#include <stdio.h>
#include <string.h>

#define PSIZE 512

int main(int argc, char* argv[])
{
int n;
size_t size;
char pass[PSIZE];

if (argc == 1)
{
fprintf(stderr, "Usage: %s password\n", argv[0]);
}
else
{
size=strlen(argv[1]);
if (size >= PSIZE)
{
fprintf(stderr, "Warning: possibility of buffer overflow on oversized password (>=%d). Exiting.\n", PSIZE);
return -1;
}

strncpy(pass, argv[1], size);

for(n=0; n<size; n++)
{
printf("%d", pass[n]);
}

printf("\n");
}

return 0;
}


I've used sample secret: example-preshared-key-secret-do-not-use-it.

sol10u6 [~]$ ./ikepconv example-preshared-key-secret-do-not-use-it
10112097109112108101451121141011151049711410110045107101121451151019911410111645100111451101111164511711510145105116

Let's start with ipsec policy settings.
Setup is as follows:

sol10u6 [~]# cat /etc/inet/ipsecinit.conf
[...]
{ laddr 10.0.2.15 raddr 10.0.2.16 } ipsec { encr_algs aes encr_auth_algs md5 sa shared }

sol10u7 [~]# cat /etc/inet/ipsecinit.conf
[...]
{ laddr 10.0.2.16 raddr 10.0.2.15 } ipsec { encr_algs aes encr_auth_algs md5 sa shared }

encr_algs aes - Use AES as Encapsulating Security Payload (ESP, IP Protocol: 50) encryption algorithm
encr_auth_algs md5 - Use MD5 as ESP authentication algorithm
sa shared - shared Security Association (SA) means the communication between the two nodes in one direction uses the same channel;
in opposite to "unique" which uses separate SA for each pair of source and destination ports

Apply IPSec policy to the system:

sol10u6 [~]# ipsecconf -a /etc/inet/ipsecinit.conf
sol10u6 [~]# ipsecconf
#INDEX 2
{ laddr 10.0.2.15 raddr 10.0.2.16 } ipsec { encr_algs aes encr_auth_algs md5 sa shared }

From now the communication is broken; IPSec has been instructed to encrypt and authenticate the traffic.
We need to provide the valid SA related to security policy.
To automate the process of key management I've used IKE daemon (in.iked).
It should be configured similary to below output:

sol10u6 [~]# cat /etc/inet/ike/config
[...]
### BEGINNING OF FILE

{
label "preshared"
local_id_type ip
local_addr 10.0.2.15
remote_addr 10.0.2.16

p1_xform
{ auth_method preshared oakley_group 5 encr_alg aes auth_alg md5 }
}

sol10u7 [~]# cat /etc/inet/ike/config
[...]
### BEGINNING OF FILE

{
label "preshared"
local_id_type ip
local_addr 10.0.2.16
remote_addr 10.0.2.15

p1_xform
{ auth_method preshared oakley_group 5 encr_alg aes auth_alg md5 }
}

oakley_group - The Oakley Diffie-Hellman group used for IKE SA key derivation. Acceptable values are currently 1 (768-bit), 2 (1024-bit), or 5 (1536-bit).

The last step is to configure the preshared secrets file.

sol10u6 [~]# cat /etc/inet/secret/ike.preshared
[...]
{
localidtype IP
localid 10.0.2.15
remoteidtype IP
remoteid 10.0.2.16
key 10112097109112108101451121141011151049711410110045107101121451151019911410111645100111451101111164511711510145105116
}

sol10u7 [~]# cat /etc/inet/secret/ike.preshared
[...]
{
localidtype IP
localid 10.0.2.16
remoteidtype IP
remoteid 10.0.2.15
key 10112097109112108101451121141011151049711410110045107101121451151019911410111645100111451101111164511711510145105116
}

key - continuous ASCII characters decimal representation of the passphrase "example-preshared-key-secret-do-not-use-it" (converted with ikepconv from the beginning of my post).
That's it: e(101)x(120)a(97)m(109)p(112)l(108)e(101)-(45)...

Start IKE daemon:

sol10u6 [~]# /usr/lib/inet/in.iked -d [debug mode]
sol10u6 [~]# /usr/lib/inet/in.iked

It's time for a simple test.

sol10u7 [~]# ping 10.0.2.15
10.0.2.15 is alive

sol10u6 [~]# snoop -c 1 src host 10.0.2.16
Using device /dev/e1000g0 (promiscuous mode)
sol10u7 -> sol10u6 ESP SPI=0xc072b272 Replay=6
1 packets captured


sol10u7 [~]# ping 10.0.2.15
10.0.2.15 is alive

sol10u6 [~]# snoop -c 1 -v src host 10.0.2.16
Using device /dev/e1000g0 (promiscuous mode)
ETHER: ----- Ether Header -----
ETHER:
ETHER: Packet 1 arrived at 17:46:25.51503
ETHER: Packet size = 150 bytes
ETHER: Destination = 8:0:27:ba:19:34, PCS Computer Systems GmbH
ETHER: Source = 8:0:27:30:9c:39, PCS Computer Systems GmbH
ETHER: Ethertype = 0800 (IP)
ETHER:
IP: ----- IP Header -----
IP:
IP: Version = 4
IP: Header length = 20 bytes
IP: Type of service = 0x00
IP: xxx. .... = 0 (precedence)
IP: ...0 .... = normal delay
IP: .... 0... = normal throughput
IP: .... .0.. = normal reliability
IP: .... ..0. = not ECN capable transport
IP: .... ...0 = no ECN congestion experienced
IP: Total length = 136 bytes
IP: Identification = 9596
IP: Flags = 0x0
IP: .0.. .... = may fragment
IP: ..0. .... = last fragment
IP: Fragment offset = 0 bytes
IP: Time to live = 255 seconds/hops
IP: Protocol = 50 (ESP)
IP: Header checksum = 7da9
IP: Source address = 10.0.2.16, sol10u7
IP: Destination address = 10.0.2.15, sol10u6
IP: No options
IP:
ESP: ----- Encapsulating Security Payload -----
ESP:
ESP: SPI = 0xc072b272
ESP: Replay = 10
ESP: ....ENCRYPTED DATA....

1 packets captured

INFO:
The IPSec definitions has been added to SMF in Solaris 10 update 7:
svc:/network/ipsec/manual-key:default
svc:/network/ipsec/ike:default
svc:/network/ipsec/ipsecalgs:default
svc:/network/ipsec/policy:default

Remember to enable ipsec/ike daemon service.

Enjoy.