Wednesday, May 22, 2013

Windows 7 profile trouble

Event ID 1511: Windows cannot find the local profile and is logging you on with a temporary profile. Changes you make to this profile will be lost when you log off.

  • Login as a different user (with admin rights)
  • Under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList, find Keys named SID.bak (like "S-1-5-21-4129847285-3583514821-2567293568-1001.bak")
  • Delete them
  • If needed, delete C:\Users\USERNAME

Labels: , , , ,

Saturday, May 11, 2013

Mediawiki with Postgres on Debian

A short guide to install Mediawiki on Debian with PostgreSQL 9.1.With a fix for this error:

"Attempting to connect to database "postgres" as superuser "postgres"... error: No database connection"

Installing packages

The server is still using Debian Squeeze, but I expect it would quite the same for the new Debian Wheezy. Here I used squeeze-backports.

 Add the backports repository if needed:

echo "deb http://backports.debian.org/debian-backports squeeze-backports main contrib non-free" >> /etc/apt/sources.list

Install everything:

apt-get update
apt-get -t squeeze-backports install apache2 postgresql-9.1 postgresql-contrib php5-pgsql
apt-get -t squeeze-backports install imagemagick libdbd-pg-perl
apt-get -t squeeze-backports install mediawiki

I use a separate IP for the wiki, so need to add it to the interface:

mcedit /etc/network/interfaces
# wiki on it's own IP
auto eth0:3
iface eth0:3 inet static
    address 192.168.10.4
    netmask 255.255.255.0

/etc/init.d/networking restart

Apache configuration

# I use the mod_rewrite module in Apache
a2enmod rewrite

# I prefer the config file in sites-enabled
# (but it's really just a symlink to /etc/mediawiki/apache.conf):
mv /etc/apache2/conf.d/mediawiki.conf /etc/apache2/sites-enabled

My virtual host config:

<VirtualHost *:80>
    ServerName wiki.example.lan
    ServerAlias wiki.example.lan
    ServerAdmin webmaster@example.com
    DocumentRoot /docs/www-wiki

    ErrorLog /var/log/apache2/wiki-error.log
    CustomLog /var/log/apache2/wiki-access.log combined

    ServerSignature On

    Alias /icons/ "/usr/share/apache2/icons/"

    RewriteEngine On
    RewriteRule ^/w(iki)?/(.*)$  http://%{HTTP_HOST}/index.php/$2 [L,NC]

    <Directory /docs/www-wiki/>
        Options +FollowSymLinks
        AllowOverride All
        # Default is Deny. Exceptions listed below with "Allow ...":
        Order Deny,Allow
        Deny from All
        Satisfy any
        # LAN
        Allow from 192.168.10.0/24
        # VPN
        Allow from 10.0.10.0/24

# If using LDAP
#        AuthType Basic
#        AuthName "Example Wiki. Requires user name and password"
#        AuthBasicProvider ldap
#        AuthzLDAPAuthoritative on
#        AuthLDAPURL ldap://localhost:389/ou=People,dc=example,dc=lan?uid
#        AuthLDAPGroupAttribute memberUid
#        AuthLDAPGroupAttributeIsDN off
#        Require ldap-group cn=users,ou=Groups,dc=example,dc=lan
    </Directory>

    # some directories must be protected
    <Directory /docs/www-wiki/config>
        Options -FollowSymLinks
        AllowOverride None
    </Directory>

    <Directory /docs/www-wiki/upload>
        Options -FollowSymLinks
        AllowOverride None
    </Directory>

    <Directory "/usr/share/apache2/icons">
        Options Indexes MultiViews
        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

Moving files

I used a directory other than the default /var/lib/mediawiki. So I had to move things over:

cp -rp /var/lib/mediawiki /docs/www-wiki

The only tricky part, with the fix:

Before starting the web configurator in http://wiki.example.lan/config/ you need to define a password for the "postgres" database user. Mediawiki will start the psql client as the www-data system user, but with the -U argument to set the user to "postgres". Even if you defined a password for the system user "postgres", this is not the password of the database user "postgres".

So you need to start psql as the postgres system user, which you can do as root using sudo -c, and then set the password inside the psql client:

sudo -u postgres psql
psql (9.1.9)
Type "help" for help.

postgres=# \password
Enter new password:
Enter it again:
postgres=# \q

If you don't do this, the Mediawiki config will end with this error:

Attempting to connect to database "postgres" as superuser "postgres"... error: No database connection

And a big pink and unhelpful error box below.

The Postgresql log (tail /var/log/postgresql/postgresql-9.1-main.log) will show:

FATAL:  password authentication failed for user "postgres"

Finally

Now you just have to move LocalSettings.php to /etc/mediawiki/.

And if you used a different install root, you have to edit it to change the MW_INSTALL_PATH:

define('MW_INSTALL_PATH','/docs/www-wiki');



Labels: , , , , , , , ,

Thursday, January 31, 2013

rsync server daemon on Mac OS X with launchctl

There are many web pages describing how to enable the rsync daemon on Mac OS X using launchd/launchctl mechanism. But I had to use a different (and simpler) plist file in LaunchDaemons to make it work across reboots on Lion (10.7.4).

(I started by following this guide , and this very similar one. And I also read this and this. In the end, what helped me getting the plist file right was this thread. Particularly this post: "For one you have both a Program and a ProgramArguments key, when you should have only one or the other (you use Program if there is just one element to the command, or ProgramArguments if there are multiple." And this one.)

This is the .plist file I used in /Library/LaunchDaemons/org.samba.rsync.plist : 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Disabled</key>
    <false/>
    <key>Label</key>
    <string>org.samba.rsync</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/rsync</string>
        <string>--daemon</string>
    </array>
    <key>RunAtLoad></key>
    <true/>
    <key>KeepAlive</key>
    <dict>
        <key>SuccessfulExit</key>
        <false/>
    </dict>
</dict>
</plist>

This is an example /etc/rsyncd.conf file:

secrets file = /etc/rsync/rsyncd.secrets
hosts allow = 192.168.1.0/24 10.0.0.1 *.cust.isp.tld

pid file = /var/run/rsyncd.pid
uid = nobody
gid = nobody
use chroot = yes
max connections = 5
syslog facility = local5list = yes
read only = yes

[shared]
path = /Users/Shared
comment = Users-Shared
uid = someuser
gid = admin
auth users = user_in_secrets

The file /etc/rsyncd.secrets looks like:

some_rsync_user:password
other_user:other_password

To install it:

sudo -s
chown root:wheel /etc/rsyncd.*
chmod 644 /etc/rsyncd.conf
chmod 600 /etc/rsyncd.secrets
launchctl load /Library/LaunchDaemons/org.samba.rsync.plist
launchctl start org.samba.rsync.plist

To check if it is installed and running:

launchctl list | grep rsync
808  -    0x7fddb4806c10.anonymous.rsync
-    0    org.samba.rsync

ps ax | grep [r]sync
  808   ??  Ss     0:00.00 /usr/bin/rsync --daemon

rsync --stats someuser@localhost::

To remove it:

sudo launchctl unload /Library/LaunchDaemons/org.samba.rsync.plist
sudo killall rsync

 

Labels: , , ,

Sunday, January 06, 2013

scripting disk partitionning in Linux - take 2

It is possible to use parted to script/automate disk partitioning in Linux, as described in "Command-line partitioning and formatting".

Another way is to use sgdisk from the GPT fdisk programs.

In Debian and derivatives, it can be installed with sudo apt-get install gdisk.

The current version 0.8.1 from the Ubuntu 12.04 repository would partition only the first 2TB of a 4 TB. disk. So you may need to get a more recent version from the downloads page. I got version 0.8.5 for x64, and that worked very well.

The following will create and format a single NTFS partition on an entire drive:

disk=/dev/sdb            # Make sure you got this right !!
label="My_Disk_Name"
echo "disk $disk will be completely erased."

sudo sgdisk -Z $disk
sudo sgdisk --new=0:0:-8M -t 1:0700 $disk
sudo sgdisk -p $disk
sudo mkntfs --verbose --fast --label "$label" --no-indexing --with-uuid ${disk}1

-Z removes any left-over partitions

--new=0:0:-8M creates a single partition from the start of the disk to 8MB before the end (just in case it's useful to not end on the very last sector)

-t 1:0700 sets the first partition we just created to type "Microsoft Basic Partition", which is the type we want for a simple NTFS partition. Linux would be -t 1:8300. Use sgdisk -L to get a list of partition types.

Note that for comfortable (and safer) manual partitioning, there is also cgdisk. It is like the old cfdisk, but works with new disks over 2TB.

Labels: , , , , , , , ,

Wednesday, January 02, 2013

Set up your own Dynamic DNS

The problem with external dynamic DNS services like dyndns.org, no-ip.com, etc. is that you constantly have to look after them. Either they are free, but they expire after 1 month and you have to go to their web site to re-activate your account. Or you pay for them, but then you need to take care of the payments, update the credit card info, etc. This is all much too cumbersome for something that should be entirely automated.

If you manage your own DNS anyway, it may be simpler in the long run to set-up your own dynamic DNS system.

Bind has everything needed. There is a lot of info on the Internet on how to do it, but what I found tended to be more complicated than becessary or insecure or both. So here is how I did it on a Debian 6 ("wheezy") server.

The steps described below are:

Initialize variables

To make it easier to copy/paste commands, we initialize a few variables

binddir="/var/cache/bind"
etcdir="/etc/bind"

(In Debian, you can use grep directory /etc/bind/named.conf.options to find the correct binddir value)

For dynamic hosts, we will use a subdomain of our main zone: .dyn.example.com.

host=myhost; zone=dyn.example.com

Create key

Most example use the dnssec-keygen command. That would create 2 files (with ugly names): one .private and one .key (public) file. This is useless since the secret key is the same in both files, and the nsupdate method doesn't use a public/private key mechanism anyway.

There is a less-known and more appropriate command in recent distributions : ddns-confgen. By default, it will just print sample entries with instructions to STDOUT. You can try it out with:

ddns-confgen -r /dev/urandom -s $host.$zone.

The options we use here are to use an "hmac-md5" algorithm instead of the default "hmac-sha256". It simplifies things with nsupdate later. And we also specify the key name to be the same as the host's name. That way, we can use a wildcard in the "update-policy" in named.conf.local and don't need to update it every time we add a host.

ddns-confgen -r /dev/urandom -q -a hmac-md5 -k $host.$zone -s $host.$zone. | tee -a $etcdir/$zone.keys

chown root:bind   $etcdir/$zone.keys
chmod u=rw,g=r,o= $etcdir/$zone.keys

Depending on how you intend to use nsupdate, you may want to also have a separate key file for every host key. nsupdate cannot use the $zone.keys file if it contains multiple keys. So you might prefer to directly create these individual keyfiles by adding something like > $etcdir/key.$host.$zone :

ddns-confgen -r /dev/urandom -q -a hmac-md5 -k $host.$zone -s $host.$zone. | tee -a $etcdir/$zone.keys > $etcdir/key.$host.$zone

chown root:bind   $zone.keys $etcdir/key.*
chmod u=rw,g=r,o= $zone.keys $etcdir/key.*

Configure bind

Create zone file

Edit $binddir/dyn.example.com :

$ORIGIN .
$TTL  3600 ; 1 hour

dyn.example.com IN SOA  dns-server.example.com. hostmaster.example.com. (
         1 ; serial (start at 1 for a dynamic zone instead of the usual date-based serial)
      3600 ; refresh by secondaries (but they get NOTIFY-ed anyway)
       600 ; retry (every 10 minutes if refresh fails)
    604800 ; expire (slaves remove the record after 1 week if they could not refresh it)
       300 ; minimum ttl for negative answers (5 minutes)
)

NS      dns-server.example.com.
$ORIGIN dyn.example.com.

Edit /etc/bind/named.conf.local

Edit /etc/bind/named.conf.local to add :

// DDNS keys
include "/etc/bind/dyn.example.com.keys";

// Dynamic zone
zone "dyn.example.com" {
    type master;
    file "/var/cache/bind/dyn.example.com";
    update-policy {
        // allow host to update themselves with a key having their own name
        grant *.dyn.example.com self dyn.example.com.;
    };
};

Reload server config

rndc reload && sleep 3 && grep named /var/log/daemon.log | tail -20

(adjust the sleep and tail values depending on the number of zones your DNS server handles, so that it has time to report any problems)

Test

If you created individual key files, or your $zone.keys file contains only a single key, you can test like this:

host=myhost; ip=10.11.12.13; zone=dyn.example.com; server=dns-server.example.com; keyfile=$etcdir/key.$host.$zone
echo -e "server $server\n zone $zone.\n update delete $host.$zone.\n update
add $host.$zone. 60 A $ip\n send" | nsupdate -k "$keyfile"

Or, more readable and with an extra TXT record:

cat <<EOF | nsupdate -k $keyfile
server $server
zone $zone.
update delete $host.$zone.
update add $host.$zone. 60 A $ip
update add $host.$zone. 60 TXT "Updated on $(date)"
send
EOF

(If you get a could not read key from $keyfile: file not found error, and the file actually exists and is owned by the bind process user, you may be using an older version of nsupdate (like the version in Debian Etch). In that case, replace nsupdate -k $keyfile with nsupdate -y "$key_name:$secret" using the key name and secret found in your key file.)

Check the result:

host -t ANY $host.$zone

It should output something like

myhost.dyn.myhost.dyn.example.com descriptive text "Update on Tue Jan  1 17:16:03 CET 2013"
example.com has address 10.11.12.13
If you try to use a file with multiple keys in the -k option to nsupdate, you will get an error like this:

... 'key' redefined near 'key'
could not read key from FILENAME.keys.{private,key}: already exists

Usage

In a /etc/network/if-up.d/ddnsupdate script.

If you have setup an update CGI page on your server, you could use something like this, letting the web server use the IP address it received anyway with your request.

#!/bin/sh

server=dns-server.example.com
host=myhost
secret="xBa2pz6ZCGQJ5obmvmp26w==" # copy the right key from $etcdir/$zone.keys

wget -O /dev/null --no-check-certificate
"https://$server/ddns/update.cgi?host=$host;secret=$secret"
Otherwise, you can use nsupdate, but you need to determine your external IP first :

#!/bin/sh

server=dns-server.example.com
zone=dyn.example.com
host=myhost
secret="xBa2pz6ZCGQJ5obmvmp26w==" # copy the right key from $etcdir/$zone.keys

ip=$(wget -q -O - http://alma.ch/myip.cgi)
cat <<EOF | nsupdate
server $server
zone $zone.
key $host.$zone $secret
update delete $host.$zone.
update add $host.$zone. 60 A $ip
update add $host.$zone. 60 TXT "Updated on $(date)"
send
EOF

An improvement on these minimal scripts might be to store the IP in a file, and only do the update if needed

Web server update.cgi

An example update.cgi :

#!/usr/bin/perl

## Use nsupdate to update a DDNS zone.

## (This could be done with the Net::DNS module. It
##  would be more portable (Windows, etc.), but also
##  more complicated. So I chose the nsupdate utility
##  that comes with Bind instead.)

# "mi\x40alma.ch", 2013

use strict;

my $VERSION = 0.2;
my $debug = 1;

my $title = "DDNS update";

my $zone     = "dyn.example.com";
my $server   = "localhost";
my $nsupdate = "/usr/bin/nsupdate";


use CGI qw(:standard);

my $q = new CGI;

my $CR = "\r\n";

print $q->header(),
      $q->start_html(-title => $title),
      $q->h1($title);


if (param("debug")) {
    $debug = 1;
};

my $host   = param("host");
my $secret = param("secret");
my $ip     = param("ip") || $ENV{"REMOTE_ADDR"};
my $time   = localtime(time);

foreach ($host, $secret, $ip) {
    s/[^A-Za-z0-9\.\/\+=]//g; # sanitize, just in case...
    unless (length($_)) {
        die "Missing or bad parameters. host='$host', secret='$secret', ip='$ip'\n";
    }
}

my $commands = qq{
server $server
zone $zone.
key $host.$zone $secret
update delete $host.$zone.
update add $host.$zone. 60 A $ip
update add $host.$zone. 60 TXT "Updated by $0 v. $VERSION, $time"
send
};

print $q->p("sending update commands to $nsupdate:"), $CR,
      $q->pre($commands), $CR;

open( NSUPDATE, "| $nsupdate" ) or die "Cannot open pipe to $nsupdate : $!\n";
print NSUPDATE $commands        or die "Error writing to $nsupdate : $!\n";
close NSUPDATE                  or die "Error closing $nsupdate : $!\n";

print $q->p("Done:"), $CR;

my @result = `host -t ANY $host.$zone`;

foreach (@result) {
    print $q->pre($_), $CR;
}


if ($debug) {
# also log received parameters
    my @lines;
    for my $key (param) {
        my @values = param($key);
        push @lines, "$key=" . join(", ", @values);
    }
    warn join("; ", @lines), "\n";
}

print $q->end_html, $CR;

__END__

Labels: , , , , , , , ,

Tuesday, June 26, 2012

USB OSX Lion installer for the impatient

To make a bootable USB disk with the Mac OS X Lion installer, the guides I found are much too verbose for my taste, and have too many cute screenshots and ads. Here is a summary for the impatient.

The downloaded installer image is deleted after install, so copy it before installing.

The installer disk image can be found in
Applications / Install Mac OS X Lion.app (right-click -> Show Package Contents) / Contents / SharedSupport / InstallESD.dmg

  • Open InstallESD.dmg. You get a "Mac OSX Install ESD" disk on the desktop
  • Partition and format the (8 GB.) USB key as standard Mac OSX Extended with journal. (The partition table defaults to MBR for USB drives; that's OK)
  • In the "Restore" tab of Disk Utility:
    • the source is the mounted image on your desktop: "Mac OS X Install ESD" (NOT the .dmg file)
    • the destination is your new USB Mac partition (not the drive itself)

Other instructions suggest using the InstallESD.dmg file as the source, and the USB key itself (not the partition it contains) as the destination. That may work too. Just don't mix both methods. I had tried that and failed, but maybe it was because I had first made a GPT partition table instead of MBR?

If you only have a 4GB key, it seems to work using Carbon Copy Cloner and de-selecting all unneeded language packs. But I haven't tried an install from such a key.

Labels: , , , ,

Sunday, June 03, 2012

Microsoft Security Essentials trouble

It seems that there is a pretty bad problem with Microsoft Security Essentials. I was surprised to notice that it wasn't running on several machines. It turns out that an automatic upgrade through Windows Update fails in a very bad way: it sort of uninstalls the old version, and then fails to install the new version. Users don't notice anything special.

Trying to re-install it by hand also fails with a very informative message (as usual for MS error messages):

Cannot complete the Security Essentials installation
An error has prevented the Security Essentials setup wizard from completing successfully. Please restart your computer and try again.
Error code:0x80070005

Of course, clicking on the "Get help" link is of no help at all.

Apparently, the code "0x80070005" means "Access denied", but there is no way to find out to what the access was denied.

Searching through the event logs reveals other errors, which I will list here in the hope that it helps other Googlers

Log Name:      System
Source:        Microsoft-Windows-WindowsUpdateClient
Event ID:      20
Task Category: Windows Update Agent
Description: Installation Failure: Windows failed to install the following update with error 0x80070643: Microsoft Security Essentials Client Update Package - KB2691905.
Log Name:      Application
Source:        Microsoft Security Client Setup
Event ID:      100
Description: HRESULT:0x80070005
Description:Cannot complete the Security Essentials installation. An error has prevented the Security Essentials setup wizard from completing successfully. Please restart your computer and try again. Error code:0x80070005. Access is denied.

And also older errors which may or may not be related:

Log Name:      Application
Source:        SideBySide
Event ID:      72
Description: Activation context generation failed for "c:\program files\microsoft security client\MSESysprep.dll".Error in manifest or policy file "c:\program files\microsoft security client\MSESysprep.dll" on line 10. The element imaging appears as a child of element urn:schemas-microsoft-com:asm.v1^assembly which is not supported by this version of Windows.

Advice found on the web which didn't work:

  • Uninstall MSSE then re-install (it was not listed in the installed programs, so I couldn't uninstall it)
  • Uninstall any other anti virus software (I didn't have any)
  • Run OneCareCleanup (silly because it was never installed)
  • etc.

Anyway, after a lot of useless searching and trying, what worked for me was to simply
rmdir /S /Q "%PROGRAMFILES%\Microsoft Security Client"

(Be careful with rmdir /s /q ! It deletes the whole folder and sub-folders without asking first!)

After that, I could re-install normally.

But it is very disturbing to see that an antivirus can just stop working without any obvious alert or user notification.

PS: It turns out that even Mark Russinovich had a problem with MSSE. His immediate error was different, but was one I also eventually found in the logs. His solution was to delete the HKCR\Installer\UpgradeCodes\11BB99F8B7FD53D4398442FBBAEF050F registry key. I had tried his procmon tool to try to find what returned "access denied", but then decided to resort to some primitive and brutal approaches first...

Labels: , ,

Wednesday, February 15, 2012

WPKG client in Windows 7

Wpkg is a fantastic tool to manage software installs on groups of Windows machines without a Windows server with Active Directory. However, I had a few problems with it in Windows 7. These were solved by replacing the Wpkg Client with Wpkg-GP.

By default, the Wpkg service runs at startup and does it's installs in the background. But very often, it failed for some reason to get a connection to the network share at the right time when the service was starting, and aborted. The log showed

WNetAddConnection2-> The network location can not be reached.

I tried to add dependencies to the service, but didn't really find a reliable solution.

So in services.msc, I changed the service startup to "Automatic (delayed)". That solved the connection problem, but brought another. If I want to upgrade Thunderbird for example, the installer has a taskkill command to close Thunderbird before upgrading it. But with a delayed start, the user probably has already started Thunderbird, and it seems quite inappropriate to just kill it while it may actually be in use.

In Windows XP, it was possible to delay the login window, so that wpkg could have done it's thing before the user logged in, but for some reason, this doesn't work in Windows 7 anymore.

So the next step was to change the configuration in settings.xml to have wpkg run at shutdown instead. This also failed because, as far as I understand, Windows Vista/7 don't allow a process to prevent shutdown for more than 5 seconds.

Finally, the solution was to remove the standard Wpkg Client, and replace it with Wpkg-GP. That seems to work. I changed the wpkg configuration back to running at startup, and added a wpkg-gp package which also takes care of uninstalling the original wpkg client:

<package id="wpkg-gp" name="Wpkg-GP" revision="%version%">

    <variable name="version" value="0.15" />

    <check type="uninstall" condition="versiongreaterorequal" path="Wpkg-GP %version% .*" value="%version%"/>

    <install cmd="%SOFTWARE%\wpkg-gp\Wpkg-GP-0.15_x64.exe /S /INI %SOFTWARE%\wpkg-gp\Wpkg-GP.ini">
        <exit code="3010" reboot="delayed" />
    </install>
    <install cmd='msiexec /x "%SOFTWARE%\wpkg\WPKG Client 1.3.14-x64.msi" /qn /norestart' />

    <upgrade cmd="%SOFTWARE%\wpkg-gp\Wpkg-GP-0.15_x64.exe /S /INI %SOFTWARE%\wpkg-gp\Wpkg-GP.ini">
        <exit code="3010" reboot="delayed" />
    </upgrade>
</package>
 

Labels: , , , , ,

Sunday, February 12, 2012

NAT over OpenVPN tunnel

Quick NAT to use an existing VPN tunnel in Linux for an additional machine (Windows XP) on your LAN.

My Ubuntu notebook uses OpenVPN to access some other networks. It is also a host to various virtual machines. I wanted a Windows XP virtual machine to access resources on the remote network through my VPN tunnel.

The virtual machine uses "bridged" networking, so it has a separate IP on the LAN. So I guess the following would also work on a physically separate machine.

On the Linux VPN tunnel host:

  • Declare variables for the network interfaces. $lan is your normal network adapter, $wan is the VPN tunnel virtual adapter. 
  • Reset iptables
  • Enable forwarding
  • Configure iptables to provide NAT masquerading
lan=wlan5; wan=tun0
iptables --flush
iptables --table nat --flush
##not needed?:# iptables --delete-chain
##not needed?:# iptables --table nat --delete-chain
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o $wan -j MASQUERADE
iptables -A FORWARD -i $lan -j ACCEPT

(This is a minimal setup, without any security! Don't use this on a host visible to the Internet!)

On the Windows XP machine:

  • Declare IP of your Linux VPN host, and name of your interface (can be seen with the ipconfig command)
  • Set the gateway and DNS to the Linux host
SET HOST=192.168.1.44
SET IFNAME=Local Area Connection 2
route change 0.0.0.0 mask 0.0.0.0 %HOST%
netsh interface ip set dns name="%IFNAME%" static %HOST%

 

Labels: , , , , ,

Tuesday, July 26, 2011

Importing root certificates into Firefox and Thunderbird

Update Feb. 2012: see at the end for an alternative for new profiles.

This is ridiculously complicated and makes me wonder whether I should just drop Firefox in Windows and go back to IE.

The problem:

How to automatically pre-import your self-signed certification authority into all user profiles for Firefox and Thunderbird.

The solution:

You need the Mozilla certutil utility (not the Microsoft certutil.exe).

In Windows, you would need to compile nss tools or use some ancient hard to find Windows binary to get it. But all my user profiles are on a Samba server, so it was much easier to do it on the server, with the added benefit of having Bash and not needing to struggle with the horrible cmd.exe.

First install the tools. In Debian, it would be:

apt-get install libnss3-tools

Then adapt this long command to your paths:

find /path/to/users-profiles -name cert8.db -printf "%h\n" | \
while read dir; do \
  certutil -A -n "My Own CA" -t "C,C,C" -d "$dir" -i "/path/to/my_own_cacert.cer"; \
done

(-printf "%h\n" prints just the directory, without the file name, one per line. That is fed to the $dir variable needed in the certutil command. The -n option is a required nickname for the certificate. -t "C,C,C" is what will make you accept any certificate signed by this CA you are importing).

See also: the certutil documentation, and a better explanation of the trust arguments (-t option).

Alternative:

The above solution works to add a certifcate to an existing profile's cert8.db. To have newly created profiles include the certificate, you need to put a good cert8.db file into the Program's directory.

  1. Either import your certificate(s) manually into an existing profile, or use the steps above to add the certificate(s) to a cert8.db file.
  2. Copy the new cert8.db to the Firefox (or Thunderbird) program directory, into a "/defaults/profile" subdirectory. (ie. "C:\Program Files (x86)\Mozilla Firefox\defaults\profile\").

This way, newly created profiles will copy this cert8.db file instead of creating a new one from scratch.

Labels: , , , , , , , , , , , ,