Tuesday, November 29, 2011

Migrating /etc/rpc into LDAP

If you are using any rpc service like NFS or NIS then you probably know the command rpcinfo. With rpcinfo you can get all rpc servives running on a remote host:

# rpcinfo -p dc01
   program vers proto   port
    100000    2   tcp    111  portmapper
    100000    2   udp    111  portmapper
...

The information about program (10000), service (portmapper) and the description (portmap, sunrpc and rpcbind) are stored in /etc/rpc:

# grep portmapper /etc/rpc
portmapper      100000  portmap sunrpc rpcbind

The information about the protocol (tcp/udp) and the port (111) are stored in /etc/services but won't matter here:

# grep 111 /etc/services
sunrpc          111/tcp    rpcbind      #SUN Remote Procedure Call
sunrpc          111/udp    rpcbind      #SUN Remote Procedure Call

If you are thinking about migrating /etc/services into LDAP - don't. Stop it. It is a real bad idea.
The information stored in /etc/rpc can be stored in LDAP. In most cases this is not necassary but possible and here is a way how to do this. To migrate the /etc/rpc file to LDAP take a look at the file first:

# cat /etc/rpc
...
portmapper      100000  portmap sunrpc rpcbind
...

The appropiate ldif for the portmapper looks like this:

# vi /etc/rpc.ldif
dn: ou=rpc,dc=example,dc=com
ou: rpc
objectClass: top
objectClass: organizationalUnit

dn: cn=portmapper,ou=rpc,dc=example,dc=com
objectClass: oncRpc
objectClass: top
cn: rpcbind
cn: portmap
cn: sunrpc
description: rpcbind
oncRpcNumber: 100000

At the top it has a organisational unit for all rpc services. You only need this once. The second object is for the portmapper itself. It contains all information shown in /etc/rpc like the service, programm and description. Now add the the file /etc/rpc.ldif to your LDAP:

# ldapadd -x -W -D 'cn=ldapadmin,dc=example,dc=com' -f /etc/rpc.ldif
Enter LDAP Password:
adding new entry "ou=rpc,dc=example,dc=com"

adding new entry "cn=portmapper,ou=rpc,dc=example,dc=com"

Configure your nsswitch.conf to look for rpc services in LDAP and disable the file lookup:

vi /etc/nsswitch.conf
...
rpc:            ldap
#rpc:           files
...

Tell your LDAP client where to look for rpc services:

# vi /etc/ldap.conf
...
nss_base_rpc            ou=rpc,dc=example,dc=com?one
...

Then check if your configuration works:

# getent rpc
portmapper      100000  rpcbind portmap sunrpc

If you disabled the file lookup and enabled the LDAP lookup only in /etc/nsswitch.conf then you should get only one entry. Now use rpcinfo to check all rpc services on a remote host again:

# rpcinfo -p dc01
   program vers proto   port
    100000    2   tcp    111  portmapper
    100000    2   udp    111  portmapper
    100024    1   udp  52036
    100024    1   tcp  35779
..

Everything after the portmapper shows up real slow. This happens because for each entry rpcinfo tries to lookup in your LDAP for an appropiate rpc service which does not contain so far. That means that you have to create a LDAP object for each entry in /etc/rpc and add it to your LDAP. Print Friendly and PDF

Monday, November 28, 2011

Available, used and free memory in HP UX

To see how much memory is consumed in HP UX use swapinfo:

# swapinfo -tam
             Mb      Mb      Mb   PCT  START/      Mb
TYPE      AVAIL    USED    FREE  USED   LIMIT RESERVE  PRI  NAME
dev       16368    1252   15116    8%       0       -    1  /dev/vg00/lvol2
reserve       -   15116  -15116
memory    16354   15707     647   96%
total     32722   32075     647   98%       -       0    -

The example above shows all devices (-a) in MB (-m) and adds a total (-t) line at the end with the sum of all memory devices. It shows a pretty heavy memory usage.

Print Friendly and PDF

Sunday, November 27, 2011

LDAP N-Way Multi-Master Replication

When you are using OpenLDAP for any reason then you should think about replication. With replication you have to setup minimum two LDAP servers. If one of your LDAP servers accidently shuts down then the other will take over. If you add content (or remove content) then you have to do it only once, the other server will get the new content by replication. Before you can use replication you have to setup a ntp server (not shown here). It is very important that both LDAP servers are using the same time. Also make sure that both server always know each other by FQDN. My current setup looks like this:


There are different type how to replicate your LDAP servers, I'll show you how to setup N-Way Multi-Master replication. Begin with your name resolution. Add all hosts (NTP server and the two LDAP servers) to /etc/hosts:

# vi /etc/hosts
...
192.168.1.73    ntp.example.com      ntp
192.168.1.70    ldap1.example.com    ldap1
192.168.1.76    ldap2.example.com    ldap2
...

Check your /etc/nsswitch.conf that it can look for hosts in files:

# vi /etc/nsswitch.conf
...
hosts:    files dns
...

In case that your DNS shuts down then the LDAP servers still know each other by looking into /etc/hosts which could get important. Next make slapd ready for replication. I assume that you have already two LDAP server up and running. My current slapd.conf looks like this for both servers:

# cat /etc/openldap/slapd.conf
# SCHEMES
include         /etc/openldap/schema/core.schema
include         /etc/openldap/schema/cosine.schema
include         /etc/openldap/schema/inetorgperson.schema
include         /etc/openldap/schema/nis.schema

# ACL
include         /etc/openldap/acl.conf

# GENERIC
pidfile         /var/run/slapd/slapd.pid
argsfile        /var/run/slapd/slapd.args
suffix          "dc=example,dc=com"
rootdn          "cn=ldapadmin,dc=example,dc=com"
rootpw          {SSHA}ycE5W7XnPe7xShTNOVbVywxutH4Dgdiy
password-hash   {MD5}
loglevel        256
sizelimit       unlimited
allow           bind_v2 bind_anon_dn

# DATABASE
database        bdb
directory       /var/lib/ldap/example.com

# BIND INDEX
index   objectClass     eq
index   uid             eq
index   cn              eq
index   memberUid       eq
index   uidNumber       eq

It holds a couple of schemes, a place for the ACL's, database etc. Next add the replication configuration to the slapd.conf on both servers:

# vi /etc/openldap/slapd.conf
...
# REPLICATION
ServerID        1 "ldap://ldap1.example.com"
ServerID        2 "ldap://ldap2.example.com"
moduleload      syncprov
overlay         syncprov
syncprov-checkpoint     10 1
syncprov-sessionlog     100
syncrepl        rid=1
                provider="ldap://192.168.1.70"
                type=refreshAndPersist
                schemachecking=on
                retry="5 10 30 +"
                searchbase="dc=example,dc=com"
                bindmethod=simple
                binddn="cn=ldapadmin,dc=example,dc=com"
                credentials="secret_clear_text_password"
syncrepl        rid=2
                provider="ldap://192.168.1.76"
                type=refreshAndPersist
                schemachecking=on
                retry="5 10 30 +"
                searchbase="dc=example,dc=com"
                bindmethod=simple
                binddn="cn=ldapadmin,dc=example,dc=com"
                credentials="secret_clear_text_password"
MirrorMode on
...

It contains both servers by FQDN, searchbase, credentials, will load the syncprov module etc. Now make sure the DIT on ldap2 is empty and that the slapd on ldap2 is not running. Then restart the slapd on ldap1:

# ssh root@ldap2
...
# kill -15 `cat /var/run/slapd/slapd.pid`
# pgrep -fl slapd
# ssh root@ldap1
...
# kill -15 `cat /var/run/slapd/slapd.pid`
# pgrep -fl slapd
# /usr/libexec/slapd -h ldap://192.168.1.70:389

If you have configured slapd for logging then you should see something similar to this on ldap1:

# tail -f /var/log/ldap.log
...
Nov 27 15:51:40 ldap1 slapd[12403]: @(#) $OpenLDAP: slapd 2.4.23 (Nov  8 2011 21:16:17) $ ^Iroot@ldap1:/tmp/openldap-2.4.23/servers/slapd
Nov 27 15:51:41 ldap1 slapd[12404]: bdb_monitor_db_open: monitoring disabled; configure monitor database to enable
Nov 27 15:51:41 ldap1 slapd[12404]: slapd starting
Nov 27 15:51:41 ldap1 slapd[12404]: slap_client_connect: URI=ldap://192.168.1.76 DN="cn=ldapadmin,dc=example,dc=com" ldap_sasl_bind_s failed (-1)
Nov 27 15:51:41 ldap1 slapd[12404]: do_syncrepl: rid=002 rc -1 retrying (9 retries left)
Nov 27 15:51:41 ldap1 slapd[12404]: conn=1000 fd=12 ACCEPT from IP=192.168.1.70:41548 (IP=192.168.1.70:389)
Nov 27 15:51:41 ldap1 slapd[12404]: conn=1000 op=0 BIND dn="cn=ldapadmin,dc=example,dc=com" method=128
Nov 27 15:51:41 ldap1 slapd[12404]: conn=1000 op=0 BIND dn="cn=ldapadmin,dc=example,dc=com" mech=SIMPLE ssf=0
Nov 27 15:51:41 ldap1 slapd[12404]: conn=1000 op=0 RESULT tag=97 err=0 text=
Nov 27 15:51:41 ldap1 slapd[12404]: conn=1000 op=1 SRCH base="dc=example,dc=com" scope=2 deref=0 filter="(objectClass=*)"
Nov 27 15:51:41 ldap1 slapd[12404]: conn=1000 op=1 SRCH attr=* +
Nov 27 15:51:46 ldap1 slapd[12404]: slap_client_connect: URI=ldap://192.168.1.76 DN="cn=ldapadmin,dc=example,dc=com" ldap_sasl_bind_s failed (-1)
Nov 27 15:51:46 ldap1 slapd[12404]: do_syncrepl: rid=002 rc -1 retrying (8 retries left)

You can see in the last to lines that the slapd tries to replicate the DIT to ldap2 (192.168.1.76). Now start the slapd on ldap2:

# ssh root@ldap2
...
/usr/libexec/slapd -h ldap://192.168.1.76:389

Now check the logfile on ldap1:

# ssh root@ldap1
...
# tail -f /var/log/ldap.log
...
Nov 27 15:55:42 ldap1 slapd[12404]: conn=1001 fd=14 ACCEPT from IP=192.168.1.76:34032 (IP=192.168.1.70:389)
Nov 27 15:55:42 ldap1 slapd[12404]: conn=1001 op=0 BIND dn="cn=ldapadmin,dc=example,dc=com" method=128
Nov 27 15:55:42 ldap1 slapd[12404]: conn=1001 op=0 BIND dn="cn=ldapadmin,dc=example,dc=com" mech=SIMPLE ssf=0
Nov 27 15:55:42 ldap1 slapd[12404]: conn=1001 op=0 RESULT tag=97 err=0 text=
Nov 27 15:55:42 ldap1 slapd[12404]: conn=1001 op=1 SRCH base="dc=example,dc=com" scope=2 deref=0 filter="(objectClass=*)"
Nov 27 15:55:42 ldap1 slapd[12404]: conn=1001 op=1 SRCH attr=* +

And on ldap2:

# ssh root@ldap2
...
# tail -f /var/log/ldap.log
...
Nov 27 15:55:42 ldap2 slapd[16336]: [ID 702911 local4.debug] @(#) $OpenLDAP: slapd 2.4.26 (Nov 20 2011 10:58:39) $
Nov 27 15:55:42 ldap2   root@ldap2:/usr/share/src/openldap-2.4.26/servers/slapd
Nov 27 15:55:42 ldap2 slapd[16337]: [ID 468869 local4.debug] bdb_monitor_db_open: monitoring disabled; configure monitor database to enable
Nov 27 15:55:42 ldap2 slapd[16337]: [ID 100111 local4.debug] slapd starting
Nov 27 15:55:42 ldap2 slapd[16337]: [ID 848112 local4.debug] conn=1000 fd=13 ACCEPT from IP=192.168.1.76:34033 (IP=192.168.1.76:389)
Nov 27 15:55:42 ldap2 slapd[16337]: [ID 215403 local4.debug] conn=1000 op=0 BIND dn="cn=ldapadmin,dc=example,dc=com" method=128
Nov 27 15:55:42 ldap2 slapd[16337]: [ID 600343 local4.debug] conn=1000 op=0 BIND dn="cn=ldapadmin,dc=example,dc=com" mech=SIMPLE ssf=0
Nov 27 15:55:42 ldap2 slapd[16337]: [ID 588225 local4.debug] conn=1000 op=0 RESULT tag=97 err=0 text=
Nov 27 15:55:42 ldap2 slapd[16337]: [ID 469902 local4.debug] conn=1000 op=1 SRCH base="dc=example,dc=com" scope=2 deref=0 filter="(objectClass=*)"
Nov 27 15:55:42 ldap2 slapd[16337]: [ID 744844 local4.debug] conn=1000 op=1 SRCH attr=* +
Nov 27 15:55:42 ldap2 slapd[16337]: [ID 405749 local4.debug] findbase failed! 32
Nov 27 15:55:42 ldap2 slapd[16337]: [ID 832699 local4.debug] conn=1000 op=1 SEARCH RESULT tag=101 err=32 nentries=0 text=
Nov 27 15:55:42 ldap2 slapd[16337]: [ID 449217 local4.debug] do_syncrep2: rid=002 LDAP_RES_SEARCH_RESULT (32) No such object
Nov 27 15:55:42 ldap2 slapd[16337]: [ID 539778 local4.debug] do_syncrep2: rid=002 (32) No such object
Nov 27 15:55:42 ldap2 slapd[16337]: [ID 218904 local4.debug] conn=1000 op=2 UNBIND
Nov 27 15:55:42 ldap2 slapd[16337]: [ID 952275 local4.debug] conn=1000 fd=13 closed
Nov 27 15:55:42 ldap2 slapd[16337]: [ID 445809 local4.debug] do_syncrepl: rid=002 rc -2 retrying (9 retries left)
Nov 27 15:55:47 ldap2 slapd[16337]: [ID 848112 local4.debug] conn=1001 fd=18 ACCEPT from IP=192.168.1.76:34034 (IP=192.168.1.76:389)
Nov 27 15:55:47 ldap2 slapd[16337]: [ID 215403 local4.debug] conn=1001 op=0 BIND dn="cn=ldapadmin,dc=example,dc=com" method=128
Nov 27 15:55:47 ldap2 slapd[16337]: [ID 600343 local4.debug] conn=1001 op=0 BIND dn="cn=ldapadmin,dc=example,dc=com" mech=SIMPLE ssf=0
Nov 27 15:55:47 ldap2 slapd[16337]: [ID 588225 local4.debug] conn=1001 op=0 RESULT tag=97 err=0 text=
Nov 27 15:55:47 ldap2 slapd[16337]: [ID 469902 local4.debug] conn=1001 op=1 SRCH base="dc=example,dc=com" scope=2 deref=0 filter="(objectClass=*)"
Nov 27 15:55:47 ldap2 slapd[16337]: [ID 744844 local4.debug] conn=1001 op=1 SRCH attr=* +
Nov 27 15:56:01 ldap2 slapd[16337]: [ID 848112 local4.debug] conn=1002 fd=19 ACCEPT from IP=192.168.1.70:39106 (IP=192.168.1.76:389)
Nov 27 15:56:01 ldap2 slapd[16337]: [ID 215403 local4.debug] conn=1002 op=0 BIND dn="cn=ldapadmin,dc=example,dc=com" method=128
Nov 27 15:56:01 ldap2 slapd[16337]: [ID 600343 local4.debug] conn=1002 op=0 BIND dn="cn=ldapadmin,dc=example,dc=com" mech=SIMPLE ssf=0
Nov 27 15:56:01 ldap2 slapd[16337]: [ID 588225 local4.debug] conn=1002 op=0 RESULT tag=97 err=0 text=
Nov 27 15:56:01 ldap2 slapd[16337]: [ID 469902 local4.debug] conn=1002 op=1 SRCH base="dc=example,dc=com" scope=2 deref=0 filter="(objectClass=*)"
Nov 27 15:56:01 ldap2 slapd[16337]: [ID 744844 local4.debug] conn=1002 op=1 SRCH attr=* +

The last lines indicates the login and replication from ldap1 (192.168.1.7.70). Your replication should work now. Finally choose any client and configure ldap.conf so it can use both LDAP servers:

# vi /etc/ldap.conf
...
BASE    dc=example,dc=com
URI     ldap://192.168.1.70:389 ldap://192.168.1.76:389
...

Add both servers as URI. When you now shutdown any LDAP server then the client can still use the remaining LDAP server. When both LDAP server are online again they will replicate each other to get  a consistent state again. Print Friendly and PDF

Friday, November 25, 2011

Creating a Slackware package

This article is outdated. See Slackware package management for a newer version.

Creating a Slackware isn't a hard job. In contrast to rpm or deb it is very easy. In this article I will show you how to compile a small (but very cool) piece of software, how to create a appropiate directory structure and finally how to create a Slackware package that you can install and remove with the default tools installpkg and removepkg. To show you how to create a Slackware package I will use Lua but you can use what ever you want. Lua is a very small and easy to compile piece of software and should work out of the box. First get the software:

# cd /usr/src
# wget http://www.lua.org/ftp/lua-5.1.4.tar.gz
...

Then extract the source and change into the new directory:

# tar xf lua-5.1.4.tar.gz
# cd lua-5.1.4

Now build the software using make but don't install it:

# make linux
...

In the src directory you have a couple of files which are more less important: two binaries (lua and luac), headers (lua.h, luaconf.h, lualib.h and lauxlib.h), a library (liblua.a) and two man pages for lua and luac (lua.1 and luac.1). The next thing you have to do is to create a directory structure that fits your system. Binaries are stored under /usr/bin, headers under /usr/include, libraries under /usr/lib and man pages under /usr/man:

# mkdir -p /usr/src/build/usr/bin
# mkdir -p /usr/src/build/usr/include
# mkdir -p /usr/src/build/usr/lib
# mkdir -p /usr/src/build/usr/man/man1
# mkdir -p /usr/src/build/install

The above commands will create a reduced layout of your systems directories under /usr/src/build. The install directory will be used later. Now copy all files to the right directory. Binaries into /usr/src/build/usr/bin, headers into /usr/src/build/usr/include and so on:

# cd /usr/src/lua-5.1.4
# cp src/lua src/luac /usr/src/build/usr/bin
# cp src/lua.h src/luaconf.h src/lualib.h src/lauxlib.h /usr/src/build/usr/include
# cp src/liblua.a /usr/src/build/usr/lib
# cp doc/lua.1 doc/luac.1 /usr/src/build/usr/man/man1

Now check that everything is at it's desired directory (tree is still one of my favorite tools):

# tree /usr/src/build
/usr/src/build
|-- install
`-- usr
    |-- bin
    |   |-- lua
    |   `-- luac
    |-- include
    |   |-- lauxlib.h
    |   |-- lua.h
    |   |-- luaconf.h
    |   `-- lualib.h
    |-- lib
    |   `-- liblua.a
    `-- man
        `-- man1
            |-- lua.1
            `-- luac.1

Now go into the unused install directory. Next you have to create a so called slack-desc file which holds the description while installing a Slackware package. It could look like this (the original file was taken from the ppp package and all texts are from http://www.lua.org/about.html):

# cd /usr/src/build/install
# vi slack-desc
# HOW TO EDIT THIS FILE:
# The "handy ruler" below makes it easier to edit a package description.  Line
# up the first '|' above the ':' following the base package name, and the '|'
# on the right side marks the last column you can put a character in.  You must
# make exactly 11 lines for the formatting to be correct.  It's also
# customary to leave one space after the ':'.

   |-----handy-ruler------------------------------------------------------|
lua: lua (a powerful, fast, lightweight, embeddable scripting language)
lua:
lua: Lua combines simple procedural syntax with powerful data description
lua: constructs based on associative arrays and extensible semantics. Lua
lua: is dynamically typed, runs by interpreting bytecode for a
lua: register-based virtual machine, and has automatic memory management
lua: with incremental garbage collection, making it ideal for
lua: configuration, scripting, and rapid prototyping.
lua:
lua:
lua:

Save the file and leave your editor. Finally create the package:

# cd /usr/src/build
# makepkg -l y -c n /tmp/lua-5.1.4-i486-1.txz

That's it. You can install the package now:

# installpkg /tmp/lua-5.1.4-i486-1.txz
Verifying package lua-5.1.4-i486-1.txz.
Installing package lua-5.1.4-i486-1.txz:
PACKAGE DESCRIPTION:
# lua (a powerful, fast, lightweight, embeddable scripting language)
#
# Lua combines simple procedural syntax with powerful data description
# constructs based on associative arrays and extensible semantics. Lua
# is dynamically typed, runs by interpreting bytecode for a
# register-based virtual machine, and has automatic memory management
# with incremental garbage collection, making it ideal for
# configuration, scripting, and rapid prototyping.
#
Package lua-5.1.4-i486-1.txz installed.

For testing purpose run lua:

# lua
lua
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> print "Hello World"
Hello World
> ^D

And remove the package (if necessary):

# removepkg lua

Removing package /var/log/packages/lua-5.1.4-i486-1...
Removing files:
  --> Deleting /usr/bin/lua
  --> Deleting /usr/bin/luac
...

As you can see creating packages for Slackware is real easy. The above shows only some basics. Print Friendly and PDF

Sunday, November 13, 2011

Migrating /etc/networks into LDAP

If you are using /etc/networks than you can move it into your LDAP. First take a look at your /etc/networks:

# cat /etc/networks
loopback        127.0.0.0
example.com     192.168.1.0
example2.com    192.168.2.0

Now create a ldif file that contains the above information:

# vi networks.ldif
dn: ou=networks,dc=example,dc=com
objectClass: organizationalUnit
objectClass: top
ou: networks

dn: cn=example.com,ou=networks,dc=example,dc=com
objectClass: top
objectClass: ipNetwork
cn: example.com
ipNetworkNumber: 192.168.1.0
ipNetmaskNumber: 255.255.255.192

dn: cn=example2.com,ou=networks,dc=example,dc=com
objectClass: top
objectClass: ipNetwork
cn: example2.com
ipNetworkNumber: 192.168.2.0
ipNetmaskNumber: 255.255.255.0

Now add it to your LDAP server:

# ldapadd -x -W -D 'cn=ldapadmin,dc=example,dc=com' -f networks.ldif
Enter LDAP Password:
adding new entry "ou=networks,dc=example,dc=com"

adding new entry "cn=example.com,ou=networks,dc=example,dc=com"

adding new entry "cn=example2.com,ou=networks,dc=example,dc=com"

Next modify your ldap.conf so it can find your LDAP entrys:

# vi /etc/ldap.conf
...
nss_base_networks       ou=networks,dc=example,dc=com?one
...

Then configure /etc/nsswitch.conf and allow your system to look for ethernet addresses in your LDAP:

# vi /etc/nsswitch.conf
...
networks:       files ldap
...

Remove all entrys from /etc/networks except for loopback:

# vi /etc/networks
loopback        127.0.0.0
#example.com     192.168.1.0
#example2.com    192.168.2.0

And finally run a query:

# getent networks
loopback              127.0.0.0
example.com           192.168.1.0
example2.com          192.168.2.0 Print Friendly and PDF

Migrating /etc/ethers into LDAP

If you are using /etc/ethers than you can move it into your LDAP. First take a look at your /etc/ethers:

# cat /etc/ethers
00:1B:21:02:96:56    192.168.1.70
00:30:05:c5:2a:ba    192.168.1.73
98:FC:11:79:37:76    192.168.1.69

Now create a ldif file that contains the above information:

# vi ethers.ldif
dn: ou=ethers,dc=example,dc=com
ou: ethers
objectClass: top
objectClass: organizationalUnit

dn: cn=192.168.1.70,ou=ethers,dc=example,dc=com
cn: 192.168.1.70
macAddress: 00:1B:21:02:96:56
objectClass: ieee802Device
objectClass: device
objectClass: top
description: Blog Server

dn: cn=192.168.1.73,ou=ethers,dc=example,dc=com
cn: 192.168.1.73
macAddress: 00:30:05:c5:2a:ba
objectClass: ieee802Device
objectClass: device
objectClass: top
description: Domain Controller


dn: cn=192.168.1.69,ou=ethers,dc=example,dc=com
cn: 192.168.1.69
macAddress: 98:FC:11:79:37:76
objectClass: ieee802Device
objectClass: device
objectClass: top
description: WLAN Router


Now add it to your LDAP server:

# ldapadd -x -W -D 'cn=ldapadmin,dc=example,dc=com' -f ethers.ldif
Enter LDAP Password:
adding new entry "ou=ethers,dc=example,dc=com"

adding new entry "cn=192.168.1.70,ou=ethers,dc=example,dc=com"

adding new entry "cn=192.168.1.73,ou=ethers,dc=example,dc=com"

adding new entry "cn=192.168.1.69,ou=ethers,dc=example,dc=com"

Next modify your ldap.conf so it can find your LDAP entrys:

# vi /etc/ldap.conf
...
nss_base_ethers        ou=ethers,dc=example,dc=com?one
...

Then configure /etc/nsswitch.conf and allow your system to look for ethernet addresses in your LDAP:

# vi /etc/nsswitch.conf
...
ethers:         files ldap
...

Finally move the original /etc/ethers to another location and test a query against your LDAP:

# mv /etc/ethers /etc/ethers.bak
# getent ethers 00:1B:21:02:96:56
0:1b:21:2:96:56 192.168.1.70
# getent ethers 192.168.1.73
0:30:5:c5:2a:ba 192.168.1.73


It will show you the IP and ethernet address for your query. Print Friendly and PDF

Migrating /etc/hosts into LDAP

If you are using /etc/hosts than you can move it into your LDAP. First take a look at your /etc/hosts:

# cat /etc/hosts
127.0.0.1        localhost
192.168.1.70     blog01
192.168.1.73     dc01
192.168.1.69     wlan01

Now create a ldif file that contains the above information:

# vi hosts.ldif
dn: ou=hosts,dc=example,dc=com
objectClass: organizationalUnit
objectClass: top
ou: hosts

dn: cn=blog01+ipHostNumber=192.168.1.70,ou=hosts,dc=example,dc=com
ipHostNumber: 192.168.1.70
objectClass: top
objectClass: ipHost
objectClass: device
cn: blog01

dn: cn=dc01+ipHostNumber=192.168.1.73,ou=hosts,dc=example,dc=com
ipHostNumber: 192.168.1.73
objectClass: top
objectClass: ipHost
objectClass: device
cn: dc01

dn: cn=wlan01+ipHostNumber=192.168.1.69,ou=hosts,dc=example,dc=com
ipHostNumber: 192.168.1.69
objectClass: top
objectClass: ipHost
objectClass: device
cn: wlan01


Now add it to your LDAP server:

# ldapadd -x -W -D 'cn=ldapadmin,dc=example,dc=com' -f hosts.ldif
Enter LDAP Password:
adding new entry "ou=hosts,dc=example,dc=com"

adding new entry "cn=blog01+ipHostNumber=192.168.1.70,ou=hosts,dc=example,dc=com"

adding new entry "cn=dc01+ipHostNumber=192.168.1.73,ou=hosts,dc=example,dc=com"

adding new entry "cn=wlan01+ipHostNumber=192.168.1.69,ou=hosts,dc=example,dc=com"

Next modify your ldap.conf so it can find your LDAP entrys:

# vi /etc/ldap.conf
...
nss_base_hosts        ou=hosts,dc=example,dc=com?one
...

Then configure /etc/nsswitch.conf and advise your system to look for your hosts in your files and your LDAP:

# vi /etc/nsswitch.conf
...
hosts:         files ldap
...

Now comment every server out that appear in /etc/hosts except for localhost and the server itself:

# vi /etc/hosts
127.0.0.1        localhost
192.168.1.70     blog01
#192.168.1.73     dc01
#192.168.1.69     wlan01

Finally test a query against your LDAP:

# getent hosts
127.0.0.1       localhost
192.168.1.70    blog01
192.168.1.70    blog01
192.168.1.73    dc01
192.168.1.69    wlan01

It will show you the IP and the hostname - as expected. The server blog01 shows up twice, one from /etc/hosts and one from your LDAP. If you try now to ping a server that is only stored in your LDAP then you will notice that it does not work:

# ping dc01
^C

Before you can ping any server which IP is stored in your LDAP you have to start nscd (Naming Service Caching Daemon). After nscd is started you can ping every server that is stored in your LDAP only:

# nscd
# ping dc01
PING dc01 (192.168.1.73) 56(84) bytes of data.
64 bytes from dc01 (192.168.1.73): icmp_req=1 ttl=64 time=0.675 ms
... Print Friendly and PDF

Backing up and restoring your LDAP

If you're using LDAP with BDB backend then you have two chances to backup your LDAP server:

1. from any client via ldapsearch
2. on the LDAP server via slapcat

To create a backup of your entire DIT you can run ldapsearch:

# ldapsearch -x -w password -D 'cn=ldapadmin,dc=example,dc=com' -b 'dc=example,dc=com' -LLL > backup.ldif

This will store the DIT in backup.ldif. The disadvantage is that you have to provide the password when you need to run it automatically (eg. in a cronjob).

To restore the DIT use ldapadd. First delete the DIT:

# ldapdelete -x -W -D 'cn=ldapadmin,dc=example,dc=com' 'dc=example,dc=com' -r
Enter LDAP Password:

Then use ldapadd to restore the entire DIT:

# ldapadd -x -W -D 'cn=ldapadmin,dc=example,dc=com' -f backup.ldif       
Enter LDAP Password:
adding new entry "dc=example,dc=com"

adding new entry "ou=groups,dc=example,dc=com"

adding new entry "cn=users,ou=groups,dc=example,dc=com"

adding new entry "ou=users,dc=example,dc=com"

adding new entry "uid=sneill,ou=users,dc=example,dc=com"

adding new entry "uid=ajolie,ou=users,dc=example,dc=com"

The next method to perform a backup is (as mentioned before) slapcat. To create a backup with slapcat, log into your LDAP server and run slapcat:

# slapcat > backup.ldif

slapcat will read /etc/openldap/slapd.conf and figure out where the database is stored:

# cat /etc/openldap/slapd.conf
...
# DATABASE
database        bdb
directory       /var/lib/ldap/example.com
...

Your complete DIT is now stored in backup.ldif. To restore the DIT simulate a data loss. Move the directory where the database is stored and create the directory only again:

# mv /var/lib/ldap/example.com/ /var/lib/ldap/data_loss
# mkdir -p /var/lib/ldap/example.com

Now restore the database:

# slapadd < backup.ldif Print Friendly and PDF

Saturday, November 12, 2011

Get the current used memory with ps

Last time I had a customer complaining about his 72GB RAM machine that it was swapping. Then he told me that all processes were using 0% RAM. He showed me something like this:

# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
...
oracle    4539  0.0  0.0    708 48264 ?        Ss    2008  16:23 ORACLE
...

This is so wrong in so many ways! From my point of view the %MEM column in ps is totally useless these days. What is much more important is the RSS column. It shows the used memory in KB. So the oracle process shown above uses 48264KB of memory. More worse was the number of processes currently running:

# ps aux | wc -l
3122

His operating system was running 3122 processes. Assuming that 122 processes were needed by the operating system then 3000 processes were used by Oracle. Now a small sample calculation:

# echo 3000*50000 | bc
150000000

3000 times 50KB are 150000000KB in sum. Now devide it by 1024 two times to get the amount in GB:

# echo 150000000/1024/1024 | bc -l
143.05114746093750000000

His machine uses about 143GB of memory, but he has only 72GB of physical memory. No wonder that his machine was swapping. By the way: 50MB of 72GB are about 0.0%.
To get the current used memory by a process use the RSS column in ps:

# ps -eo rss,cmd
  RSS CMD
...
 6716 /usr/bin/python /opt/mailman/bin/qrunner --runner=RetryRunner:0:1 -s
..
 9160 /usr/bin/httpd -k start
...

Now you can do some real useful stuff. First remove the cmd column in ps:

# ps -eo rss
  RSS
...
26700
 1000
 5200
...

Then use grep to get rid of the ps header:

# ps -eo rss | grep -v RSS
...
26700
 1000
 5200
...

Finally you can use awk to get the sum of all values:

# ps -eo rss | grep -v RSS | awk '{total = total + $1} END {print total}'
246000

This is one of my small webservers - just a very simple LAMP environment. It has 2GB memory available and is currently using ~240MB. Print Friendly and PDF

Monday, November 7, 2011

SmartPCI56(UCB1500) 56K Modem with Slackware

I got another Modem PCI card - again. This time something like this:

# lspci
...
00:09.0 Modem: Philips Semiconductors SmartPCI56(UCB1500) 56K Modem (rev 01)
...

After doing some research on the Internet I found out that the card should work with slmodem (just like the internal modem from my old Toshiba). So I downloaded and extracted the latest release:

# cd /usr/src
# wget http://linmodems.technion.ac.il/packages/smartlink/slmodem-2.9.11-20110321.tar.gz
...
# tar xfz slmodem-2.9.11-20110321.tar.gz
# cd slmodem-2.9.11-20110321

Then I compiled it:

# make
...
# make install
...

After the compilation finished I tried to load the driver and took a look at the logs:

# modprobe slamr
# dmesg
...
[  323.131435] slamr: module license 'Smart Link Ltd.' taints kernel.
[  323.131455] Disabling lock debugging due to kernel taint
[  323.182214] slamr: SmartLink AMRMO modem.
[  323.182260] slamr: device 1131:3400 is grabbed by another driver

Whoops - device is grabbed by another driver? Never had this issue before, lspci has given me some more information:

# lspci -vn
00:09.0 0703: 1131:3400 (rev 01) (prog-if 00 [Generic])
        Subsystem: 1131:3400
        Flags: bus master, medium devsel, latency 64, IRQ 11
        I/O ports at da00 [size=16]
        Capabilities: [80] Power Management version 1
        Kernel driver in use: serial
        Kernel modules: slamr

After doing some more research on the internet about this I found the hint: there is a driver called ungrab-winmodem which has to be loaded before slamr and that will free the device. Again, I download the software and extracted it:

# cd /usr/src
# wget http://linmodems.technion.ac.il/packages/smartlink/ungrab-winmodem-20090716.tar.gz
...
# tar xfz ungrab-winmodem-20090716.tar.gz
# cd ungrab-winmodem-20090716

Again I compiled it:

# make
...
# make install
...

Finally I unloaded the slamr driver and tried to get it to work with the ungrab-winmodem driver:

# rmmod slamr
# modprobe ungrab-winmodem
# modprobe slamr

A look at the logs:

# dmesg
...
[ 1913.669335] device 1131:3400 is grabbed by driver serial: try to release
[ 1920.208990] slamr: SmartLink AMRMO modem.
[ 1920.209191] slamr: probe 1131:3400 SL1500 card...
[ 1920.209226] slamr 0000:00:09.0: AMD756: dev [1131:3400], router PIRQ 2 get IRQ 11
[ 1920.209237] slamr 0000:00:09.0: found PCI INT A -> IRQ 11
[ 1920.213816] slamr: mc97 codec is SIL22
[ 1920.213891] slamr: slamr0 is SL1500 card.

Perfect! It seems that the device is ready again. I have just to start the slmodemd daemon again with my prior published script:

# vi /etc/rc.d/rc.slmodemd
#!/bin/bash

echo "Starting slmodemd:  slmodemd --country=GERMANY /dev/slamr0"

# stop slmodemd
if [[ `pgrep -x slmodemd` ]]; then
  kill -9 `pgrep -x slmodemd`
fi

# un/re-load module
if [[ `lsmod | grep slamr | awk 'BEGIN {FS=" "} {print $1}'` != "" ]]; then
  rmmod slamr
fi
modprobe ungrab-winmodem
modprobe slamr

# create devices
cd /dev
for dev in 0 1 2 3; do
  if [[ ! -c /dev/slamr$dev ]]; then
    mknod -m 600 /dev/slamr$dev c 242 $dev
  fi
done

# start slmodemd
(slmodemd --country=GERMANY /dev/slamr0 > /dev/null 2>&1) &

Make it executable and start it:

# chmod 755 /etc/rc.d/rc.slmodemd
# /etc/rc.d/rc.slmodemd

It will unload the slamr driver first (if necessary) and then load the ungrab-winmodem and slamr driver again, create all devices etc. At the end your modem will be available at /dev/ttySL0 Print Friendly and PDF

Sunday, November 6, 2011

PCTel Inc HSP MicroModem 56 with Slackware

Yesterday I got an old PCI Modem card, something with pctel anything. I was wondering if I could get it to run, so I did some research on the Internet and found the pctel software for Linux. The disapointment was that i will only compile on 32bit machines. Anyway, I setup my old Athlon 800MHz desktop with the pctel card and installed the current Slackware release (13.37). Then I donwloaded the driver from http://linmodems.technion.ac.il/pctel-linux/welcome.html:

# cd /usr/src
# wget http://linmodems.technion.ac.il/pctel-linux/pctel-0.9.7-9-rht-12.tar.gz
...
# tar xf pctel-0.9.7-9-rht-12.tar.gz
# cd pctel-0.9.7-9-rht-12/src

And installed it:

# ./configure -auto
...
detecting your modem...found. Your modem is a pct789 type modem.
# make
...
# make install
...

Then I loaded the driver and checked the system logs:

# modprobe pctel
# dmesg
...
[  413.713914] pctel_hw(155): PCTel hardware driver version 0.9.7-9-rht-9 for PCT789
[  413.732268] pctel(481): pctel v0.1 loaded
[  413.732343] pctel_pci(753): device 134d:7892 is grabbed by driver serial: try to release
[  413.762381] pctel_hw 0000:00:0a.0: AMD756: dev [134d:7892], router PIRQ 3 get IRQ 12
[  413.762396] pctel_hw 0000:00:0a.0: found PCI INT A -> IRQ 12
[  413.762440] pctel_pci(238): PCTel device[0000:00:0a.0](0x50) found 134d:7892 (rev 02), iobase=0xdc00, irq=12.
[  413.762453] pctel_pci(628): Setup PCI port: port 0xdc00, irq 12, type 0, membase   (null), ops   (null)
[  413.762480] ttyS_PCTEL0 at I/O 0xdc00 (irq = 12) is a PCTel

The log above shows the device to use: /dev/ttys_PCTEL0
You can use this device now with any software like minicom.
Now check with lspci:

# lspci -vn
...
00:0a.0 0703: 134d:7892 (rev 02) (prog-if 00 [Generic])
        Subsystem: 134d:0001
        Flags: medium devsel, IRQ 12
        I/O ports at dc00 [size=64]
        Capabilities: [40] Power Management version 2
        Kernel driver in use: pctel_hw
        Kernel modules: pctel
...

The output shows that the PCI card is controlled by the pctel module and is ready to use now.

If you installed the driver and get an error while loading the driver like:

# modprobe pctel
WARNING: Error inserting pctel_hw (/lib/modules/2.6.37.6/misc/pctel_hw.ko): Invalid module format
FATAL: Error inserting pctel (/lib/modules/2.6.37.6/misc/pctel.ko): Invalid module format

Then check the system logs:

# dmesg
...
[ 2862.819296] linmodem: version magic '2.6.37.6-smp SMP mod_unload 686 ' should be '2.6.37.6 mod_unload 486 '
[ 2879.444270] pctel_hw: version magic '2.6.37.6-smp SMP mod_unload 686 ' should be '2.6.37.6 mod_unload 486 '

It shows that the module was build for 2.6.37.6-smp, but your current running kernel 2.6.37.6. Check with uname:

# uname -r
2.6.37.6

In this case you have to install the packages kernel-huge-smp-2.6.37.6_smp-i686-2 and kernel-modules-smp-2.6.37.6_smp-i686-2, reconfigure lilo and reboot. If necassary rebuild the module (like above) and then load the module again which should work now. Also make sure that the module is in the right modules path:

# ls -lah /lib/modules/`uname -r`/misc/
...
-rw-r--r-- 1 root root  16K Nov  6 12:59 linmodem.ko
-rw-r--r-- 1 root root  17K Nov  6 12:59 pctel.ko
-rw-r--r-- 1 root root 1.1M Nov  6 12:59 pctel_hw.ko

If everything is right (kernel version and modules path) then you should have no problem to load and use the pctel driver Print Friendly and PDF