Welcome to zewaren.net. This site presents myself and mostly archives the solutions to some problems I once had.

How to authenticate ProFTPd against a LDAP server with client certificates

AttachmentSize
File mod_ldap_ssl_cert.patch10.09 KB
Not so frequently asked questions and stuff: 

Problem

If you are the paranoid type, you might have restricted connections to your LDAP server to clients with SSL client certificates.

Unfortunately, the support of client certificate is missing in a lot of implementation of LDAP clients.

Solution

Go to mod_ldap and download the sources.

Apply the following patch:

--- mod_ldap.c.orig 2012-02-01 12:34:22.587267553 +0100
+++ mod_ldap.c   2012-02-01 12:34:04.636276785 +0100
@@ -161,7 +161,14 @@
             *ldap_attr_memberuid = "memberUid",
             *ldap_attr_ftpquota = "ftpQuota",
             *ldap_attr_ftpquota_profiledn = "ftpQuotaProfileDN",
-            *ldap_attr_ssh_pubkey = "sshPublicKey";
+            *ldap_attr_ssh_pubkey = "sshPublicKey",
+            *ldap_tls_ca_cert_dir,
+            *ldap_tls_ca_cert_file,
+            *ldap_tls_cert_file,
+            *ldap_tls_cipher_suite,
+            *ldap_tls_crl_file,
+            *ldap_tls_dh_file,
+            *ldap_tls_key_file;
 #ifdef HAS_LDAP_INITIALIZE
 static char *ldap_server_url;
 #endif /* HAS_LDAP_INITIALIZE */
@@ -171,7 +178,9 @@
            ldap_forcedefaultuid = 0, ldap_forcedefaultgid = 0,
            ldap_forcegenhdir = 0, ldap_protocol_version = 3,
            ldap_dereference = LDAP_DEREF_NEVER,
-           ldap_search_scope = LDAP_SCOPE_SUBTREE;
+           ldap_search_scope = LDAP_SCOPE_SUBTREE,
+           ldap_tls_crl_check = -1,
+           ldap_tls_require_cert = -1;
 static struct timeval ldap_querytimeout_tp;
 
 static uid_t ldap_defaultuid = -1;
@@ -214,6 +223,86 @@
   struct berval bindcred;
 #endif
 
+  if (ldap_tls_ca_cert_dir) {
+    ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTDIR, ldap_tls_ca_cert_dir);
+    if (ret != LDAP_OPT_SUCCESS) {
+      pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_CACERTDIR option failed: %s", ldap_err2string(ret));
+      pr_ldap_unbind();
+      return -1;
+    }
+    pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_CACERTDIR to %s", ldap_tls_ca_cert_dir);  
+  }
+  
+  if (ldap_tls_ca_cert_file) {
+    ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, ldap_tls_ca_cert_file);
+    if (ret != LDAP_OPT_SUCCESS) {
+      pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_CACERTFILE option failed: %s", ldap_err2string(ret));
+      pr_ldap_unbind();
+      return -1;
+    }
+    pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_CACERTFILE to %s", ldap_tls_ca_cert_file);  
+  }
+  
+  if (ldap_tls_cert_file) {
+    ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CERTFILE, ldap_tls_cert_file);
+    if (ret != LDAP_OPT_SUCCESS) {
+      pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_CERTFILE option failed: %s", ldap_err2string(ret));
+      pr_ldap_unbind();
+      return -1;
+    }
+    pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_CERTFILE to %s", ldap_tls_cert_file);  
+  }
+  
+  if (ldap_tls_cipher_suite) {
+    ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, ldap_tls_cipher_suite);
+    if (ret != LDAP_OPT_SUCCESS) {
+      pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_CIPHER_SUITE option failed: %s", ldap_err2string(ret));
+      pr_ldap_unbind();
+      return -1;
+    }
+    pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_CIPHER_SUITE to %s", ldap_tls_cipher_suite);  
+  }
+  
+  if (ldap_tls_dh_file) {
+    ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_DHFILE, ldap_tls_dh_file);
+    if (ret != LDAP_OPT_SUCCESS) {
+      pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_DHFILE option failed: %s", ldap_err2string(ret));
+      pr_ldap_unbind();
+      return -1;
+    }
+    pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_DHFILE version to %s", ldap_tls_dh_file);  
+  }
+  
+  if (ldap_tls_key_file) {
+    ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_KEYFILE, ldap_tls_key_file);
+    if (ret != LDAP_OPT_SUCCESS) {
+      pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_KEYFILE option failed: %s", ldap_err2string(ret));
+      pr_ldap_unbind();
+      return -1;
+    }
+    pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": pr_ldap_connect(): set LDAP_OPT_X_TLS_KEYFILE to %s", ldap_tls_key_file);  
+  }
+
+  if (ldap_tls_crl_check != -1) {
+    ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CRLCHECK, (void *)&ldap_tls_crl_check);
+    if (ret != LDAP_OPT_SUCCESS) {
+      pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_CRLCHECK option failed: %s", ldap_err2string(ret));
+      pr_ldap_unbind();
+      return -1;
+    }
+    pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_CRLCHECK to %d", ldap_tls_crl_check);  
+  }  
+  
+  if (ldap_tls_require_cert != -1) {
+    ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, (void *)&ldap_tls_require_cert);
+    if (ret != LDAP_OPT_SUCCESS) {
+      pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_REQUIRE_CERT option failed: %s", ldap_err2string(ret));
+      pr_ldap_unbind();
+      return -1;
+    }
+    pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_REQUIRE_CERT to %d", ldap_tls_require_cert);  
+  }
+
 #ifdef HAS_LDAP_INITIALIZE
   pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": attempting connection to %s", ldap_server_url ? ldap_server_url : "(null)");
 
@@ -1876,6 +1965,130 @@
   return PR_HANDLED(cmd);
 }
 
+MODRET
+set_ldap_tls_ca_cert_dir(cmd_rec *cmd)
+{
+  CHECK_ARGS(cmd, 1);
+  CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL);
+
+  add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
+  return PR_HANDLED(cmd);
+}
+
+MODRET
+set_ldap_tls_ca_cert_file(cmd_rec *cmd)
+{
+  CHECK_ARGS(cmd, 1);
+  CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL);
+
+  add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
+  return PR_HANDLED(cmd);
+}
+
+MODRET
+set_ldap_tls_cert_file(cmd_rec *cmd)
+{
+  CHECK_ARGS(cmd, 1);
+  CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL);
+
+  add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
+  return PR_HANDLED(cmd);
+}
+
+MODRET
+set_ldap_tls_cipher_suite(cmd_rec *cmd)
+{
+  CHECK_ARGS(cmd, 1);
+  CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL);
+
+  add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
+  return PR_HANDLED(cmd);
+}
+
+MODRET
+set_ldap_tls_crl_check(cmd_rec *cmd)
+{
+  int value;
+  config_rec *c;
+
+  CHECK_ARGS(cmd, 1);
+  CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL);
+
+  if (strcasecmp(cmd->argv[1], "none") == 0) {
+    value = LDAP_OPT_X_TLS_CRL_NONE;
+  } else if (strcasecmp(cmd->argv[1], "peer") == 0) {
+    value = LDAP_OPT_X_TLS_CRL_PEER;
+  } else if (strcasecmp(cmd->argv[1], "all") == 0) {
+    value = LDAP_OPT_X_TLS_CRL_ALL;
+  } else {
+    CONF_ERROR(cmd, "LDAPTLSCrlCheck: expected a valid LDAP_OPT_X_TLS_CRLCHECK option (none, peer, all).");
+  }
+
+  c = add_config_param("LDAPTLSCrlCheck", 1, NULL);
+  c->argv[0] = pcalloc(c->pool, sizeof(int));
+  *((int *) c->argv[0]) = value;
+  return PR_HANDLED(cmd);
+}
+
+MODRET
+set_ldap_tls_dh_file(cmd_rec *cmd)
+{
+  CHECK_ARGS(cmd, 1);
+  CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL);
+
+  add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
+  return PR_HANDLED(cmd);
+}
+
+MODRET
+set_ldap_tls_crl_file(cmd_rec *cmd)
+{
+  CHECK_ARGS(cmd, 1);
+  CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL);
+
+  add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
+  return PR_HANDLED(cmd);
+}
+
+MODRET
+set_ldap_tls_key_file(cmd_rec *cmd)
+{
+  CHECK_ARGS(cmd, 1);
+  CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL);
+
+  add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
+  return PR_HANDLED(cmd);
+}
+
+MODRET
+set_ldap_tls_require_cert(cmd_rec *cmd)
+{
+  int value;
+  config_rec *c;
+
+  CHECK_ARGS(cmd, 1);
+  CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL);
+
+  if (strcasecmp(cmd->argv[1], "never") == 0) {
+    value = LDAP_OPT_X_TLS_NEVER;
+  } else if (strcasecmp(cmd->argv[1], "hard") == 0) {
+    value = LDAP_OPT_X_TLS_HARD;
+  } else if (strcasecmp(cmd->argv[1], "demand") == 0) {
+    value = LDAP_OPT_X_TLS_DEMAND;
+  } else if (strcasecmp(cmd->argv[1], "allow") == 0) {
+    value = LDAP_OPT_X_TLS_ALLOW;
+  } else if (strcasecmp(cmd->argv[1], "try") == 0) {
+    value = LDAP_OPT_X_TLS_TRY;    
+  } else {
+    CONF_ERROR(cmd, "LDAPTLSRequireCert: expected a valid LDAP_OPT_X_TLS_REQUIRE_CERT option (never, hard, demand, allow, try).");
+  }
+
+  c = add_config_param("LDAPTLSRequireCert", 1, NULL);
+  c->argv[0] = pcalloc(c->pool, sizeof(int));
+  *((int *) c->argv[0]) = value;
+  return PR_HANDLED(cmd);
+}
+
 static int
 ldap_getconf(void)
 {
@@ -2059,6 +2272,22 @@
         "(&(", ldap_attr_memberuid, "=%v)(objectclass=posixGroup))", NULL);
     }
   }
+  
+  ldap_tls_ca_cert_dir =  (char *)get_param_ptr(main_server->conf, "LDAPTLSCACertDir", FALSE);
+  ldap_tls_ca_cert_file = (char *)get_param_ptr(main_server->conf, "LDAPTLSCACertFile", FALSE);
+  ldap_tls_cert_file =    (char *)get_param_ptr(main_server->conf, "LDAPTLSCertFile", FALSE);
+  ldap_tls_cipher_suite = (char *)get_param_ptr(main_server->conf, "LDAPTLSCipherSuite", FALSE);
+  ldap_tls_crl_file =     (char *)get_param_ptr(main_server->conf, "LDAPTLSCrlFile", FALSE);
+  ldap_tls_dh_file =      (char *)get_param_ptr(main_server->conf, "LDAPTLSDHFile", FALSE);
+  ldap_tls_key_file =     (char *)get_param_ptr(main_server->conf, "LDAPTLSKeyFile", FALSE);
+  ptr = get_param_ptr(main_server->conf, "LDAPTLSCrlCheck", FALSE);
+  if (ptr) {
+    ldap_tls_crl_check = *((int *) ptr);
+  }
+  ptr = get_param_ptr(main_server->conf, "LDAPTLSRequireCert", FALSE);
+  if (ptr) {
+    ldap_tls_require_cert = *((int *) ptr);
+  }  
 
   return 0;
 }
@@ -2092,7 +2321,15 @@
   { "LDAPGenerateHomedirPrefixNoUsername", set_ldap_genhdirprefixnouname, NULL },
   { "LDAPForceGeneratedHomedir", set_ldap_forcegenhdir, NULL },
   { "LDAPDefaultQuota", set_ldap_defaultquota, NULL },
-  { "LDAPGroups", set_ldap_grouplookups, NULL },
+  { "LDAPTLSCACertDir", set_ldap_tls_ca_cert_dir, NULL },
+  { "LDAPTLSCACertFile", set_ldap_tls_ca_cert_file, NULL },
+  { "LDAPTLSCertFile", set_ldap_tls_cert_file, NULL },
+  { "LDAPTLSCipherSuite", set_ldap_tls_cipher_suite, NULL },
+  { "LDAPTLSCrlCheck", set_ldap_tls_crl_check, NULL },
+  { "LDAPTLSCrlFile", set_ldap_tls_crl_file, NULL },
+  { "LDAPTLSDHFile", set_ldap_tls_dh_file, NULL },
+  { "LDAPTLSKeyFile", set_ldap_tls_key_file, NULL },
+  { "LDAPTLSRequireCert", set_ldap_tls_require_cert, NULL },
   { NULL, NULL, NULL },
 };

Then, configure ProFTPd ([/usr/local]/etc/proftpd.conf), for example:

LDAPServer ldaps://aaa.bbb.ccc.ddd:636/??one
LDAPAuthBinds on
LDAPBindDN "cn=user,dc=example,dc=net" "password"
LDAPUsers "ou=people,o=organisation,dc=example,dc=net"
LDAPTLSCACertFile /usr/local/etc/certs/example-ca-crt.pem
LDAPTLSCertFile /usr/local/etc/certs/example-ftp-crt.pem
LDAPTLSKeyFile /usr/local/etc/certs/exemple-key.pem

The available options are:

  • LDAPTLSCACertDir
  • LDAPTLSCACertFile
  • LDAPTLSCertFile
  • LDAPTLSCipherSuite
  • LDAPTLSCrlCheck
  • LDAPTLSCrlFile
  • LDAPTLSDHFile
  • LDAPTLSKeyFile
  • LDAPTLSRequireCert

You can find more information about what they do by typing "man 3 ldap_set_option".

How to install FreeBSD 90 via PXE from anywhere (i.e. without a NFS server)

Not so frequently asked questions and stuff: 

The situation

You want to install FreeBSD on another machine. You don't want to use a NFS server, because you are either on a Windows computer or because you simply want to boot the installer using pxeboot or gpxe.

From FreeBSD 9.0, the bootonly CD does not use a mfs file system anymore, so instead of just copying the existing one, you either need to make one yourself or find one on the internet.

We will be using one from mfsbsd, from Martin Matuška.
http://mfsbsd.vx.sk/

[2014-06-15] Update: I've been told by email that mfsbsd now provides images directly from their website:
http://mfsbsd.vx.sk/files/images/
Thanks to Roman Makarov for the information.

Step 1: build the FreeBSD image disk

Create some dirs:

# mkdir /tmp/build
# mkdir /tmp/build/iso.mnt
# mkdir /tmp/build/hd.mnt
# cd /tmp/build

Get the image:

fetch http://mfsbsd.vx.sk/iso/mfsbsd-9.0-amd64.iso
mfsbsd-9.0-amd64.iso                          100% of   28 MB 3904 kBps

Mount the image:

# mdconfig -a -t vnode -f /tmp/build/mfsbsd-9.0-amd64.iso
md0
# mount_cd9660 /dev/md0 /tmp/build/iso.mnt/

Create a hard disk image. Be sure to choose the right size.

# dd if=/dev/zero of=/tmp/build/FreeBSD-9.0-RELEASE-amd64-bootonly-mfsbsd.hd bs=1m count=30
30+0 records in
30+0 records out
31457280 bytes transferred in 0.371249 secs (84733651 bytes/sec)
# mdconfig -a -t vnode -f /tmp/build/FreeBSD-9.0-RELEASE-amd64-bootonly-mfsbsd.hd
md1
# fdisk -B -I /dev/md1
******* Working on device /dev/md1 *******
fdisk: invalid fdisk partition table found
fdisk: Class not found
# bsdlabel -B -w /dev/md1
# bsdlabel -e /dev/md1
# /dev/md1:
8 partitions:
#        size   offset    fstype   [fsize bsize bps/cpg]
  a:    61424       16    4.2BSD        0     0
  c:    61440        0    unused        0     0         # "raw" part, don't edit
/tmp/EdDk.LJ3WUbdhRH: 5 lines, 212 characters
# newfs /dev/md1a
/dev/md1a: 30.0MB (61424 sectors) block size 16384, fragment size 2048
        using 4 cylinder groups of 7.50MB, 480 blks, 960 inodes.
super-block backups (for fsck -b #) at:
 160, 15520, 30880, 46240
# mount /dev/md1a /tmp/build/hd.mnt

Copy the boot files from the iso to the disk image:

# cp -r iso.mnt/* hd.mnt/

Umount everything:

# umount /tmp/build/hd.mnt
# mdconfig -d -u 1
# umount /tmp/build/iso.mnt
# mdconfig -d -u 0

You now have a bootable mfsBSD image disk.

Step2: Boot the image disk

Download pxelinux.0.
Download memdisk. You can find it packaged with syslinux: http://www.kernel.org/pub/linux/utils/boot/syslinux/

Create pxelinux config file (pxelinux.cfg/default):

DEFAULT fbsd
 
LABEL fbsd
 kernel memdisk
 append initrd=/FreeBSD-9.0-RELEASE-amd64-bootonly-mfsbsd.hd harddisk raw

Setup your DHCP and TFTP servers to serve the directory and you're good.

Once booted, login as root and launch the usual installer:

bsdinstall

Sources

How to get ruby's strftime to have localized dates

Not so frequently asked questions and stuff: 

Here is how to use ruby's strftime in French:

require 'date'
newv = [
{'Janvier' => 1, 'Février' => 2, 'Mars' => 3, 'Avril' => 4, 'Mai' => 5, 'Juin' => 6, 'Juillet' => 7, 'Août' => 8, 'Septembre'=> 9, 'Octobre' =>10, 'Novembre' =>11, 'Décembre' => 12},
{'Dimanche' => 0, 'Lundi' => 1, 'Mardi' => 2, 'Mercredi' => 3, 'Jeudi'=> 4, 'Vendredi' => 5, 'Samedi' => 6},
{'jan' => 1, 'fév' => 2, 'mar' => 3, 'avr' => 4, 'mai' => 5, 'juin' => 6, 'juil' => 7, 'aoû' => 8, 'sep' => 9, 'oct' =>10, 'nov' =>11, 'déc' => 12},
{'dim' => 0, 'lun' => 1, 'mar' => 2, 'mer' => 3, 'jeu' => 4, 'ven' => 5, 'sam' => 6},
[nil] + %w(Janvier Février Mars Avril Mai Juin Juillet Août Septembre Octobre Novembre Décembre),
%w(Dimanche Lundi Mardi Mercredi Jeudi Vendredi Samedi),
[nil] + %w(jan fév mar avr mai juin juil aoû sep oct nov déc),
%w(dim lun mar mer jeu ven sam)
]
Date::FRENCH_MONTHS=newv[0]
Date::FRENCH_DAYS=newv[1]
Date::FRENCH_ABBR_MONTHS=newv[2]
Date::FRENCH_ABBR_DAYS=newv[3]
Date::FRENCH_MONTHNAMES=newv[4]
Date::FRENCH_DAYNAMES=newv[5]
Date::FRENCH_ABBR_MONTHNAMES=newv[6]
Date::FRENCH_ABBR_DAYNAMES=newv[7]

class Time

  def strftime_french(format)
    format = format.dup
    format.gsub!(/%a/, Date::FRENCH_ABBR_DAYNAMES[self.wday])
    format.gsub!(/%A/, Date::FRENCH_DAYNAMES[self.wday])
    format.gsub!(/%b/, Date::FRENCH_ABBR_MONTHNAMES[self.mon])
    format.gsub!(/%B/, Date::FRENCH_MONTHNAMES[self.mon])
    self.strftime(format)
  end
end

class Date

  def strftime_french(format)
    format = format.dup
    format.gsub!(/%a/, Date::FRENCH_ABBR_DAYNAMES[self.wday])
    format.gsub!(/%A/, Date::FRENCH_DAYNAMES[self.wday])
    format.gsub!(/%b/, Date::FRENCH_ABBR_MONTHNAMES[self.mon])
    format.gsub!(/%B/, Date::FRENCH_MONTHNAMES[self.mon])
    self.strftime(format)
  end
end

I did not want to override strftime, because a lot of libraries use it, and this can lead to unexpected behavior (e.g. the imap protocol use dates like 05 Feb 2012 which would get translated as 05 Fév 2012 and trigger an error).

Boot Wester Digital's diagnostic tool "Data Lifeguard Diagnostic" using PXE

AttachmentSize
Package icon pxe-diag-westerndigital-Diag504fCD.zip506.76 KB

The system used here is a Debian Lenny.

Create the image:

You will need:

  • Data Lifeguard Diagnostic for DOS (CD)
  • FreeDOS
zwm-server:~/western# wget "ftp://ftp.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.0/fdboot.img"
zwm-server:~/western# wget "http://support.wdc.com/download/dlg/Diag504fCD.iso"

Mount the FreeDOS image and the CD:

zwm-server:~/western# mkdir fdboot ourimage DiagCD
zwm-server:~/western# mount -o loop fdboot.img fdboot
zwm-server:~/western# mount -o loop Diag504fCD.iso DiagCD/

Create and mount a 2MB fat image:

zwm-server:~/western# dd if=/dev/zero of=ourimage.img bs=1M count=2
zwm-server:~/western# apt-get install dosfstools
zwm-server:~/western# mkfs.msdos ourimage.img
zwm-server:~/western# mount -o loop ourimage.img ourimage

Copy the FreeDOS files and the CD contents to the newly created image disk:

zwm-server:~/western# cp -r fdboot/* ourimage/
zwm-server:~/western# mkdir ourimage/western
zwm-server:~/western# cp -r DiagCD/* ourimage/western/

Umount eveything:

zwm-server:~/western# umount ourimage/
zwm-server:~/western# umount DiagCD/
zwm-server:~/western# umount fdboot/

Copy the boot sector from the original FreeDOS image to ours:

zwm-server:~/western# dd if=fdboot.img of=ourimage.img bs=1 count=446 seek=62 skip=62 conv=notrunc

Boot the image:

What you need:

  • pxelinux.0
  • memdisk
  • pxelinux's config file (pxelinux.cfg/default):
    DEFAULT wd_iso
    
    LABEL wd_iso
      KERNEL memdisk
      INITRD ourimage.img
    

Boot your computer, start FreeDOS and run the Wester Digital utility from the western folder.

Sources:

Boot Hitachi's drive test tool "Drive Fitness" using PXE

What you need:

How to use jails with epair with FreeBSD 9.0

Not so frequently asked questions and stuff: 

Introduction

System used:

FreeBSD testjails 9.0-RELEASE FreeBSD 9.0-RELEASE #1: Thu Jan 19 10:47:03 CET 2012     root@testjails:/usr/obj/usr/src/sys/JAILKERNEL  i386

Build and install a kernel including VIMAGE, epair and briged interfaces

Configure the kernel: (/usr/src/sys/i386/conf/JAILKERNEL)

include GENERIC

cpu             I686_CPU
ident           JAILKERNEL

# Virtual networking for jail
options         VIMAGE
device          epair
device          if_bridge

# The nullFS to mount local directory
options         NULLFS

Make and install the kernel:

cd /usr/src
make buildkernel KERNCONF=JAILKERNEL
make installkernel KERNCONF=JAILKERNEL
reboot

Create the jail's environement

mkdir /jails/somejail/
cd /usr/src
make buildworld
make installworld DESTDIR=/jails/somejail/
make distribution DESTDIR=/jails/somejail/
echo 'hostname="testjail.example.com"' >> /jails/somejail/etc/rc.conf
echo 'nameserver 8.8.8.8"' >> /jails/somejail/etc/resolv.conf
mkdir /jails/somejail/usr/ports

Start and use the jail manually

Start the jail:

# jail -c vnet name=testjail host.hostname=testjail path=/jails/somejail persist
# jls
   JID  IP Address      Hostname                      Path
     1  -               testjail                      /jails/somejail

Create the virtual ethernet cable:

# ifconfig epair0 create
epair0a
# ifconfig epair0b vnet testjail

Create the bridge:

# ifconfig bridge0 create
# ifconfig bridge0 addm em0 addm epair0a
# ifconfig bridge0 up

Configure the network on both sides:

# ifconfig em0 192.168.1.1/24
# ifconfig
em0: flags=8943 metric 0 mtu 1500
        options=98
        inet 192.168.1.1 netmask 0xffffff00 broadcast 192.168.1.255
        nd6 options=29
        media: Ethernet autoselect (1000baseT )
        status: active
epair0a: flags=8943 metric 0 mtu 1500
        options=8
        nd6 options=29
        media: Ethernet 10Gbase-T (10Gbase-T )
        status: active
bridge0: flags=8843 metric 0 mtu 1500
        nd6 options=29
        id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
        maxage 20 holdcnt 6 proto rstp maxaddr 100 timeout 1200
        root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
        member: epair0a flags=143
                ifmaxaddr 0 port 5 priority 128 path cost 14183
        member: em0 flags=143
                ifmaxaddr 0 port 1 priority 128 path cost 20000
# jexec testjail ifconfig epair0b 192.168.1.2/24
# jexec testjail ifconfig
lo0: flags=8008 metric 0 mtu 16384
        options=3
        nd6 options=21
epair0b: flags=8843 metric 0 mtu 1500
        options=8
        inet6 fe80::c0:a4ff:fe00:60b%epair0b prefixlen 64 scopeid 0x2
        inet 192.168.1.2 netmask 0xffffff00 broadcast 192.168.1.255
        nd6 options=21
        media: Ethernet 10Gbase-T (10Gbase-T )
        status: active

Test the connection:

# jexec testjail ping -c 1 192.168.1.1
PING 192.168.1.1 (192.168.3.223): 56 data bytes
64 bytes from 192.168.1.1: icmp_seq=0 ttl=64 time=0.795 ms

--- 192.168.1.1 ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.795/0.795/0.795/0.000 ms

# jexec testjail route add default 192.168.1.250
add net default: gateway 192.168.1.250

# jexec testjail ping -c 1 example.net
PING example.net (192.0.43.10): 56 data bytes
64 bytes from 192.0.43.10: icmp_seq=0 ttl=243 time=92.568 ms

--- example.net ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 92.568/92.568/92.568/0.000 ms

Stop the jail:

# jail -r testjail
enceinte# jls
   JID  IP Address      Hostname                      Path

Clean the network:

# ifconfig epair0a destroy
# ifconfig bridge0 destroy

Start the jail automatically

As of 2011/08/01, /etc/rc.d/jail has problems using the new jail command (v2), so you must patch it if you want to use vnets:
http://www.freebsd.org/cgi/query-pr.cgi?pr=142972
Also, you need this patch to be able to put the epair interface in the jail's vnet after it is created, but before starting the jail's rc.script (via earlypoststart entries in rc.conf).

See also:
http://lists.freebsd.org/pipermail/freebsd-stable/2012-January/065556.html

My original /etc/rc.d/jail script was revision 1.47.

Here is the modified patch that worked for me:
fbsd9_rcdjail147_vnet_patch

Then, in /etc/rc.conf:

#
# Jails networking
#
cloned_interfaces="bridge0"
ifconfig_bridge0="addm em0"

#
# Jails configuration
#
jail_enable="YES"
jail_v2_enable="YES"
jail_list="testjail"

jail_testjail_name="testjail"
jail_testjail_hostname="testjail.example.net"
jail_testjail_devfs_enable="YES"
jail_testjail_rootdir="/jails/somejail"
jail_testjail_vnet_enable="YES"
jail_testjail_exec_prestart0="ifconfig epair0 create"
jail_testjail_exec_prestart1="ifconfig bridge0 addm epair0a"
jail_testjail_exec_prestart2="ifconfig epair0a up"
jail_testjail_exec_earlypoststart0="ifconfig epair0b vnet testjail"
jail_testjail_exec_afterstart0="ifconfig lo0 127.0.0.1"
jail_testjail_exec_afterstart1="ifconfig epair0b 192.168.1.2/24 up"
jail_testjail_exec_afterstart2="route add default 192.168.1.250"
jail_testjail_exec_afterstart3="/bin/sh /etc/rc"
jail_testjail_exec_poststop0="ifconfig bridge0 deletem epair0a"
jail_testjail_exec_poststop1="ifconfig epair0a destroy"

Then:

# /etc/rc.d/jail onestart testjail
Configuring jails:.
Starting jails:epair0a
add net default: gateway 192.168.1.250
Setting hostname: testjail.example.com.
Creating and/or trimming log files.
Starting syslogd.
ELF ldconfig path: /lib /usr/lib /usr/lib/compat
a.out ldconfig path: /usr/lib/aout /usr/lib/compat/aout
Clearing /tmp (X related).
Updating motd:.
Starting cron.

Thu Jan 19 11:45:24 UTC 2012
 testjail.example.net.
testjails# jls
   JID  IP Address      Hostname                      Path
     1  -               testjail.example.com          /jails/somejail
# jexec testjail ifconfig
lo0: flags=8049 metric 0 mtu 16384
        options=3
        inet 127.0.0.1 netmask 0xff000000
        inet6 ::1 prefixlen 128
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
        nd6 options=21
epair0b: flags=8843 metric 0 mtu 1500
        options=8
        inet6 fe80::c0:a4ff:fe00:70b%epair0b prefixlen 64 scopeid 0x2
        inet 192.168.1.2 netmask 0xffffff00 broadcast 192.168.1.255
        nd6 options=21
        media: Ethernet 10Gbase-T (10Gbase-T )
        status: active
# jexec testjail ping -c 1 example.net
PING example.net (192.0.43.10): 56 data bytes
64 bytes from 192.0.43.10: icmp_seq=0 ttl=243 time=92.799 ms

--- example.net ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 92.799/92.799/92.799/0.000 ms

Sources:

How to install FreeBSD 82 via PXE from anywhere (i.e. without a NFS server)

Not so frequently asked questions and stuff: 

The situation

You want to install FreeBSD on another machine. You don't want to use a NFS server, because you are either on a Windows computer or because you simply want to boot the installer using pxeboot or gpxe.

Step 1: build the FreeBSD image disk

Create some dirs:

# mkdir /tmp/build
# mkdir /tmp/build/iso.mnt
# mkdir /tmp/build/hd.mnt
# mkdir /tmp/build/mfs.mnt
# cd /tmp/build

Get the image:

# wget ftp://ftp.fr.freebsd.org/pub/FreeBSD/ISO-IMAGES-i386/8.2/FreeBSD-8.2-RELEASE-i386-bootonly.iso
--2011-12-15 09:30:41--  ftp://ftp.fr.freebsd.org/pub/FreeBSD/ISO-IMAGES-i386/8.2/FreeBSD-8.2-RELEASE-i386-bootonly.iso
           => `FreeBSD-8.2-RELEASE-i386-bootonly.iso.1'
Resolving ftp.fr.freebsd.org... 88.191.250.131
Connecting to ftp.fr.freebsd.org|88.191.250.131|:21... connected.
Logging in as anonymous ... Logged in!
==> SYST ... done.    ==> PWD ... done.
==> TYPE I ... done.  ==> CWD (1) /pub/FreeBSD/ISO-IMAGES-i386/8.2 ... done.
==> SIZE FreeBSD-8.2-RELEASE-i386-bootonly.iso ... 49262592
==> PASV ... done.    ==> RETR FreeBSD-8.2-RELEASE-i386-bootonly.iso ... done.
Length: 49262592 (47M) (unauthoritative)

100%[======================================>] 49,262,592  2.57M/s   in 18s

2011-12-15 09:30:59 (2.62 MB/s) - `FreeBSD-8.2-RELEASE-i386-bootonly.iso.1' saved [49262592]

Mount the image:

# mdconfig -a -t vnode -f /tmp/build/FreeBSD-8.2-RELEASE-i386-bootonly.iso
md0
# mount_cd9660 /dev/md0 /tmp/build/iso.mnt/

Create a hard disk image. Be sure to choose the right size.

# dd if=/dev/zero of=/tmp/build/FreeBSD-8.2-RELEASE-i386-bootonly.hd bs=1m count=60
60+0 records in
60+0 records out
62914560 bytes transferred in 0.737012 secs (85364374 bytes/sec)
# mdconfig -a -t vnode -f /tmp/build/FreeBSD-8.2-RELEASE-i386-bootonly.hd
md1
# fdisk -B -I /dev/md1
******* Working on device /dev/md1 *******
fdisk: invalid fdisk partition table found
fdisk: Class not found
# bsdlabel -B -w /dev/md1
# bsdlabel -e /dev/md1
# /dev/md1:
8 partitions:
#        size   offset    fstype   [fsize bsize bps/cpg]
  a:   122864       16    4.2BSD        0     0
  c:   122880        0    unused        0     0         # "raw" part, don't edit

# newfs /dev/md1a
/dev/md1a: 60.0MB (122864 sectors) block size 16384, fragment size 2048
        using 4 cylinder groups of 15.00MB, 960 blks, 1920 inodes.
super-block backups (for fsck -b #) at:
 160, 30880, 61600, 92320
# mount /dev/md1a /tmp/build/hd.mnt

Copy the boot files from the iso to the disk image:

# cp -r /tmp/build/iso.mnt/boot /tmp/build/hd.mnt/boot

Umount everything:

# umount /tmp/build/hd.mnt
# mdconfig -d -u 1
# umount /tmp/build/iso.mnt
# mdconfig -d -u 0

You now have a bootable FreeBSD installer image disk.

Step2: Boot the image disk

Download pxelinux.0.
Download memdisk. You can find it packaged with syslinux: http://www.kernel.org/pub/linux/utils/boot/syslinux/

Create pxelinux config file (pxelinux.cfg/default):

DEFAULT fbsd

LABEL fbsd
 kernel memdisk
 append initrd=/FreeBSD82.hd harddisk

Setup your DHCP and TFTP servers to serve the directory and you're good.

Sources

How to kill javaw.exe

Not so frequently asked questions and stuff: 

The situation

You have some java processes running on your system but you can't stop or kill them. You tried using the task manager and sysinternals' process explorer.

The solution

Find the PID of your java process

C:\>jps -l -v
3100 sun.tools.jps.Jps -Dapplication.home=C:\Program Files\Java\jdk1.6.0_24 -Xms 8m
2904 C:\Program -Xms40m -Xmx256m -XX:MaxPermSize=96m -DXPCOM.RUNTIME=C:\Program
Files\Texas Instruments\ccsv4\DebugServer\win32 -Dxpcom.bridge.executeOnDedicate
dThread=yes -Dorg.eclipse.swt.browser.XULRunnerPath=C:\Program Files\Texas Instrument\ccsv4\DebugServer\win32 -Dosgi.instance.area.default=file:/C:/Documents and Settings/SomeUser/Mes documents/workspace/

Here we want to kill the nasty eclipse process 2904.

Use taskkill.

C:\>taskkill /F /PID 2904
Opération réussie : le processus avec PID 2904 a été terminé.

If you don't use option /F, the command will still execute successfully but nothing will happen.

Shells and editors configuration

This is part of my shell configuration

FreeBSD

This configuration allow, when using tmux:

  • Ctrl+arrow to move around words in tcsh and zsh
  • Ctrl+arrow to move around words in vim
  • Shift+arrow to selects characters in vim
  • Ctrl+Shift+arrow to selects words in vim
  • Many other things

~/.vimrc

set nocompatible
set tabstop=4
set shiftwidth=2
set showmatch
set guioptions-=T
set vb t_vb=
set ruler
set nohls
set incsearch
set virtualedit=all
set bs=2

syntax on
colorscheme zenburn
if !empty($TMUX)
    if &term =~ 'xterm-256color'
      " Disable Background Color Erase (BCE) so that color schemes
      " work properly when Vim is used inside tmux and GNU screen.
      " See also http://snk.tuxfamily.org/log/vim-256color-bce.html
      set term=cons25
      set t_ut=
      set t_Co=256

      "Ctrl + Arrows => Move fast
      map ^[[1;5C w
      map ^[[1;5D b
      imap ^[[1;5C w
      imap ^[[1;5D b
      "Del => Delete
      map ^[[3~ x
      imap ^[[3~ x

      "Shift + Arrow => Select
      map      ^[[1;2A vk
      map      ^[[1;2B vj
      map      ^[[1;2D vh
      map      ^[[1;2C vl
      inoremap ^[[1;2A vk
      vnoremap ^[[1;2A k
      inoremap ^[[1;2B vj
      vnoremap ^[[1;2B j
      inoremap ^[[1;2C vl
      vnoremap ^[[1;2C l
      inoremap ^[[1;2D vh
      vnoremap ^[[1;2D h

      "Simple arrows in visual mode gets back to normal mode
      vnoremap ^[[C vl
      vnoremap ^[[D vh
      vnoremap ^[[A vk
      vnoremap ^[[B vj

      "Shift + Select + Arrow => Select fast
      map      ^[[1;6C vw
      map      ^[[1;6D vb
      map      ^[[1;6A vk
      map      ^[[1;6B vj
      inoremap ^[[1;6C vw
      inoremap ^[[1;6D vb
      inoremap ^[[1;6A vk
      inoremap ^[[1;6B vj
      vnoremap ^[[1;6C w
      vnoremap ^[[1;6D b
      vnoremap ^[[1;6A k
      vnoremap ^[[1;6B j

      "End, Home
      map      ^[[F $
      map      ^[[H 0
      inoremap ^[[F $
      inoremap ^[[H 0
      vnoremap ^[[F $
      vnoremap ^[[H 0
      "Ctrl + End, Home => Document Start, End
      map      ^[[1;5F G
      map      ^[[1;5H gg
      inoremap ^[[1;5F G
      inoremap ^[[1;5H gg
      vnoremap ^[[1;5F G
      vnoremap ^[[1;5H gg
      map      ^[[1;2F v$
      map      ^[[1;2H v0
      inoremap ^[[1;2F v$
      inoremap ^[[1;2H v0
      vnoremap ^[[1;2F $
      vnoremap ^[[1;2H 0

      "PgUp, PgDown
      map      ^[[5~ 
      map      ^[[6~ 

      " backspace in Visual mode deletes selection
      vnoremap ^? d

    endif
else
    if &term =~ 'xterm-256color'
        set t_Co=256
        map ^[[C w
        map ^[[D b
        imap ^[[C w
        imap ^[[D b
    endif
endif

ZenBurn Color scheme

.cshrc, relevant parts

if ( $?tcsh ) then
        bindkey "^W" backward-delete-word
        bindkey -k up history-search-backward
        bindkey -k down history-search-forward
        bindkey "^[[1;5D" backward-word
        bindkey "^[[1;5C" forward-word
endif

.zshrc, relevant parts

bindkey "^[OD" backward-word
bindkey "^[OC" forward-word
bindkey "^[[1;5C" forward-word
bindkey "^[[1;5D" backward-word
bindkey "^[[1~" beginning-of-line
bindkey "^[[4~" end-of-line
bindkey "^[[3~" delete-char

.tmux.conf, relevant parts

set -g default-terminal "xterm-256color-tmuxed-zwm"
set -g terminal-overrides "xterm*:colors=256:XT:smcup@:rmcup@:kUP5=\eOA:kDN5=\eOB:kLFT5=\eOD:kRIT5=\eOC"
set-option -gw xterm-keys on

To get the full, experience, you need to SSH to your box using Futty.

Be sure to use a version with Ctrl+Shift+Keys enabled.

See: http://code.google.com/p/futty/issues/detail?id=23

How to do a netbios name reverse lookup using samba.

Not so frequently asked questions and stuff: 

How to do a netbios name reverse lookup using samba

Use nmblookup

# nmblookup -A 10.0.9.124
Looking up status of 10.0.9.124
        ZWM-SERVER      <00> -         H <ACTIVE>
        ZWM-SERVER      <03> -         H <ACTIVE>
        ZWM-SERVER      <20> -         H <ACTIVE>
        REZID           <1e> - <GROUP> H <ACTIVE>
        REZID           <00> - <GROUP> H <ACTIVE>

        MAC Address = 00-00-00-00-00-00

If you're on debian on don't have the command, install the package named samba-common-bin:

# apt-get install samba-common-bin

Sources:

Pages

Subscribe to Front page feed