Encrypted home on Ubuntu using cryptoloop
August 19th, 2006
Install pam_mount:
# apt-get install libpam-mount
Configure Ubuntu to load the loop and cryptoloop kernel modules during boot or else pam_mount won’t be able to mount the cryptoloop devices:
# cat >> /etc/modules
loop
cryptoloop
Configure PAM to use pam_mount for authentication and session management. PAM authentication captures the user login password, while PAM session set ups the cryptoloop device and mounts it during log on, and unmounts the cryptoloop during log off.
# echo “@include common-pammount” >> /etc/pam.d/common-auth
# echo “@include common-pammount” >> /etc/pam.d/common-session
Sets up some variables used to make the rest of the steps a little bit easier and more generic:
# USER=solana
# SIZE=2048
# KEYSIZE=128
The meaning of the previous variables is:
- USER defines the username.
- SIZE defines how much space to allocate for the file-based cryptoloop, as a quantity expressed in MiB.
- KEYSIZE defines the AES keysize used to encrypt the data. Valid keysizes are 128, 192 and 256.
Creates the loop file and fills it with random junk:
# dd if=/dev/urandom of=/home/${USER}.img bs=1M count=${SIZE}
Generate an AES random encryption key, encrypts it with the user log on password and stores it:
# dd if=/dev/urandom bs=1c count=$((${KEYSIZE}/8)) | openssl enc -aes-${KEYSIZE}-ecb > /home/${USER}.key
When prompted for the passphrase, enter the user’s log on password.
Loads the cryptoloop kernel driver (if not already):
# modprobe -q cryptoloop
Finds the first loopback device available:
# LOOP=$(losetup -f)
Make sure that ${LOOP} is something like /dev/loop0.
Sets up the cryptoloop device:
# openssl enc -d -aes-${KEYSIZE}-ecb -in /home/${USER}.key | losetup -e aes -k ${KEYSIZE} -p0 ${LOOP} /home/${USER}.img
When asked for the passphrase, just enter the user’s log on password.
Make a new ext3 filesystem on top of the cryptoloop device:
# mkfs.ext3 ${LOOP}
Frees the cryptoloop device:
# losetup -d ${LOOP}
Configure pam_mount:
# echo “volume ${USER} auto – /home/${USER}.img /home/${USER} loop,user,exec,encryption=aes,keybits=${KEYSIZE} aes-${KEYSIZE}-ecb /home/${USER}.key” >> /etc/security/pam_mount.conf
Installing Ubuntu Linux on a MacBook Pro
August 19th, 2006
codeThis article describes how to install Ubuntu Linux on a MacBook Pro laptop. Although I chose Ubuntu Linux as the Linux distribution, you can easily replace that for whatever distro you like the most. It’s only a matter of choice and freedom.
Download Ubuntu Linux
Download the latest desktop ISO image from Ubuntu’s web site and burn it down onto a blank CD. I will use this CD to install Ubuntu Linux on the MacBook Pro and also for recovery purpouses in case anything goes wrong.
Install Apple Boot Camp
Boot Camp is some sort of BIOS emulation to allow some legacy operating systems that don’t support EFI to work on MacBooks. Although Linux does support EFI, it seems it only works reliably when used on Itanium-based machines and in combination with the ELILO bootloader. Anyways, I will use plain LILO and BIOS emulation provided by Boot Camp.
Download Boot Camp from Apple’s Web site and install it. After installation, go to Applications -> Utilities and launch Boot Camp.
The first time you run it, Boot Camp will offer to burn some Windows drivers onto a blank CD. We can skip this step since we are not going to install Windows. Next, we need to shrink the Mac OS X HFS+ volume in order to leave space for the Linux volume. I chose to assign 23GB of disk space to Linux, but your mileage may vary.
Install rEFIt
rEFIt is an extremely powerful GUI EFI bootloader. It allows you to boot up Mac OS X, Linux and even Winblows, graphically, while also allows one to peek inside EFI (using the built-in EFI shell).
Download rEFIt from here. You can choose whatever format you like — Mac disk image, ISO image or tar.gz. The latest version, at the time of this writing, was this.
Extract the /efi directory from the file you downloaded and place it into the root directory of your Mac OS X boot volume. For the tar.gz file you can run:
# tar -C /tmp -zxvf refit-bin-0.7.tar.gz
# mv /tmp/refit-bin-0.7/efi /
Install rEFIt:
# cd /efi/refit
# sh ./enable-always.sh
Install Ubuntu Linux
Once Boot Camp has been installed, the Mac OS X volume shrinked to leave space for the Linux partition, and rEFIt installed into your Mac OS X boot volume, we will start the Ubuntu Linux installation.
Insert the Ubuntu Linux CD into the CD-ROM, reboot while holding down the C key — boot from the CD-ROM — and wait for Ubuntu Linux to finish starting up. You should be dropped into a brown-coloured beautiful desktop.
Before installing Ubuntu Linux, make sure you have network connectivity. For wired Ethernet it’s usually as easy as plugging in an Ethernet cable and waiting for a DHCP lease. For Wireless it depends on whether you can get associated with a public/open Wireless Access Point. Fortunately, the MacBook Pro uses an Atheros-based wireless card, so it will just work out of the box, even when using WEP, WPA or WPA2.
To configure for wired Ethernet and DHCP:
# ifconfig eth0 up
# dhclient eth0
To configure for wireless Ethernet, via a public hot spot and DHCP:
# ifconfig ath0 up
# iwconfig ath0 essid GoogleWifi
# dhclient ath0
Check you have network connectivity, usually by pinging a well know host. I tend to use W.X.Y.Z as a check — don’t think it’s a good idea to tell the whole world the machine I use for ping purposes as it system administrator won’t like it much:
# ping -c W.X.Y.Z
PING W.X.Y.Z (W.X.Y.Z) 56(84) bytes of data.
64 bytes from W.X.Y.Z: icmp_seq=1 ttl=235 time=179 ms
64 bytes from W.X.Y.Z: icmp_seq=2 ttl=235 time=179 ms
64 bytes from W.X.Y.Z: icmp_seq=3 ttl=235 time=178 ms
— W.X.Y.Z ping statistics —
3 packets transmitted, 3 received, 0% packet loss, time 2007ms
rtt min/avg/max/mdev = 178.278/178.993/179.612/0.734 ms
Now, double click the Installer icon you will find on the desktop. This will start the Install Wizard that will guide you during the installation process.
The next screens are rather easy to go through: choose your language, keyboard layout, username and password, time zone, etc. The important steps begin once you are prompted about the partition layout. Choose to manually edit the partition table and click on Forward. The next screen allows making changes to the partition layout. I strongly recommend on not making any changes and click on Forward again.
On the next screen, make sure the EFI GPT partition is not mounted — click into the dropdown list and select the blank entry. Mount the Linux partition, usually /dev/sda3 as / and then click on Forward.
- NOTE:I didn’t create a swap partition, so the installer complained at a later point. If your computer has enough RAM (>192MB), you can go on with the installation and create a swap file once the system is installed and ready.
At the end of the installation, GRUB will fail to install. That’s totally normal. Instead, we will use and install LILO as the boot loader. Open a terminal and run the following commands:
# mount -t proc none /target/proc
# mount -o bind /dev /target/dev
# chroot /target
The last command places ourselves into the Linux filesystem of the newly installed Ubuntu Linux.
Next, install LILO and the SMP kernel — since MacBooks have an Intel Core Duo:
# apt-get install lilo lilo-doc linux-686-smp
# cat > /etc/lilo.conf << EOF
> boot=/dev/sda3
> default=Ubuntu
>
> map=/boot/map
> delay=20
> image=/vmlinuz initrd=/initrd.img
> root=/dev/sda3
> append=noapic
> label=Ubuntu
> read-only
> EOF
# lilo -b /dev/sda
# exit
- NOTE: I had to append the noapic option to the kernel command line due to a sporadic kernel panic while booting related to the APIC stuff. Since these MacBook laptops are SMP systems, APIC is expected to replace the aging ISA-compatible way of assigning IRQs. However, it doesn’t seem to work reliably, at least on my laptop.
Exit the chroot jail — usually by running “exit” or typing ^D — and double check you are not inside the chroot jail anymore:
# parted
(parted) print
Disk geometry for /dev/sda: 0kB - 100GB Disk label type: gpt Number Start End Size File system Name Flags 1 200kB 210MB 210MB fat32 EFI system partition boot 2 210MB 76GB 76GB hfs+ Merged_untitled 3 77GB 100GB 23GB fat32 Untitled
(parted) set 3
Flag to change? boot/hidden/raid/lvm/hp-service/msftres? boot
New state? on/[off]? on
(parted) quit
Parted understands the new EFI GPT partition table format, while fdisk does not. I think that’s the reason why, after the Ubuntu installer formats the partition and starts copying files onto it, all partitions except sda1 vanish from fdisk‘s listing.
Since EFI boot support is still experimental, we will use standard LILO (it seems GRUB uses certain BIOS calls which are still not supported by Boot Camp BIOS emulation). However, this requires syncing the EFI GPT partition table with the old-fashioned, BIOS-compatible MBR partition table or else Linux won’t boot. We will do this syncing from the rEFIt main menu at a later point.
Check that LILO got installed by running:
# hexdump -C /dev/sda | less
Look for the string LILO at the beginning of the listing. If it’s missing, try reinstalling LILO again.
Before rebooting, we need to unmount all the partitions that we mounted before:
# umount /target/proc
# umount /target/dev
# umount /target
I’ve seen the last command failing to unmount the root filesystem a couple of times. It seems some process has opened files on it, but I’ve been unable to catch it up by using fuser or lsof.
# reboot
Enter the rEFIt Partition editor and make sure the MBR/GPT maps are in sync.
Now, we are ready to boot into Linux, although there are some rough small things we need to get fixed, like the video resolution and aspect ratio.
Resources:
Linksys, OpenWRT and multiple VLANs
July 19th, 2006
The Cisco Linksys WRT54G/GS/GL is made up of a six-port configurable switch, a standard Ethernet controller (usually a Broadcom controller named eth0) and a Wireless controller (usually a Broadcom controller named eth1).
The following diagram tries to illustrate the different components that made up the Cisco Linksys and how are they interconnected:
Linksys rear
Trunk Internet 1 2 3 4 port number
--- --- --- --- --- ---
|5| |4| |3| |2| |1| |0| switch port number
--- --- --- --- --- ---
| | | |
| vlan1 |----- vlan0 -----|
|
| Miniswitch
----------------------------------------
| Linux
|
| ---- vlan0 -> LAN
| |
|----- eth0 -
|
---- vlan1 -> Internet/WAN
The standard Ethernet controller is attached to the sixth port (port #5) of the switch and is configured as a 802.1q VLAN trunk port. This allows running several VLANs using a single connection to the switch.
By default, OpenWRT configures two per-VLAN network interfaces:
vlan0:stands on the VLAN0 (the Local Area Network which comprises the four ports labeled as 1, 2, 3 and 4 at the rear of the box).
vlan1:stands on the WAN network (the port labeled Internet at the rear of the box).
The VLAN configuration is controlled using NVRAM variables. The variable labeled vlan0ports defines which switch ports are assigned onto the VLAN0, while vlan1ports defines which switch ports are assigned onto the VLAN1.
This is the default NVRAM configuration:
nvram set vlan0ports="3 2 1 0 5*" nvram set vlan0hwname=et0 nvram set vlan1ports="4 5" nvram set vlan1hwname=et0
vlan0ports:states that ports #3, #2, #1 and #0 (the ports labeled as 1, 2, 3 and 4 at the rear of the box) are assigned onto VLAN0. Additionally, port #5 is also assigned onto VLAN0.
The asterisk sitting besides the 5 means VLAN0 is the default, native VLAN for this port, so any untagged traffic is considered to belong to VLAN0.
vlan1ports:states that port #4 (the port labeled as Internet at the rear of the box) is assigned onto VLAN1. Additionally, port #5 is also assigned onto VLAN1 since it’s a trunk port.
The lack of an asterisk means VLAN1 is not the default, native VLAN for this port.
NOTE: vlannhwname needs to have a value assigned to it, even when it’s value is never used by the init scripts. This value is usually et0.
NOTE: Care must be exercised as ports numbers are zero-based, as illustrated before, and the sixth-port (port #5) must be assigned to every VLAN, since it is an VLAN trunk port.
The following code snippet from /etc/init.d/S10boot shows how the init script tells the switch which ports are onto which VLANs:
# configure the switch based on nvram
[ -d /proc/switch/eth0 ] && {
for nr in $(seq 0 15); do
vp="$(nvram get vlan${nr}ports)"
[ -z "$vp" -o -z "$(nvram get vlan${nr}hwname)" ] || {
echo "$vp" > /proc/switch/eth0/vlan/$nr/ports
}
done
}
We can also see that up to sixteen VLANs are supported by the switch.
Custom VLANs
The Linksys and OpenWRT combination is so flexible that we can configure additional VLANs. In fact, I was looking to add an additional administrative VLAN (VLAN2) granting me full access to the box while I could restrict access from the LAN and WAN to the minimum — for example, by using additional firewall rules.
This is depicted in the following figure:
Linksys rear
Trunk Internet 1 2 3 4 port number
--- --- --- --- --- ---
|5| |4| |3| |2| |1| |0| switch port number
--- --- --- --- --- ---
| | | | |
| vlan1 vlan2 |-- vlan0 --|
|
| Linksys
----------------------------------------
| Linux
|
| ---- vlan0 -> LAN
| |
|----- eth0 ---- vlan1 -> Internet/WAN
|
---- vlan2 -> Administrative VLAN
To achieve this configuration, we need to remove port #3 (labeled as 1 at the rear of the box) from VLAN0 and assign it onto VLAN2. We also need to add port #5 to the VLAN2 since it is the VLAN trunk port used to carry the traffic from the switch to Linux through the standard Ethernet controller:
nvram set vlan0ports="2 1 0 5*" nvram set vlan0hwname=et0 nvram set vlan1ports="4 5" nvram set vlan1hwname=et0 nvram set vlan2ports="3 5" nvram set vlan2hwname=et0
I’ve defined three custom NVRAM variables that will get used by an additional init script to configure the VLAN2 as an administrative VLAN, granting full access to the box:
adm_ifname:defines the Linux network interface name assigned to the administrative VLAN, in the form of
vlann, where n is the VLAN number.adm_ipaddr:defines the IP address for the administrative interface.
adm_netmask:defines the network mask for the administrative interface.
For example:
nvram set adm_ifname=vlan2 nvram set adm_ipaddr=192.168.0.100 nvram set adm_netmask=255.255.0.0
I’ve also coded up an additional init script, named /etc/init.d/S41network, used to bring up the administrative interface. I’ve decided not to fiddle with /etc/init.d/S40network to avoid breaking things and having problems during upgrades.
These are the contents of /etc/init.d/S41network:
#!/bin/sh
IFNAME=$(nvram get adm_ifname)
VLAN=${IFNAME##vlan}
IPADDR=$(nvram get adm_ipaddr)
NETMASK=$(nvram get adm_netmask)
vconfig add eth0 $VLAN
ifconfig vlan${VLAN} up ${IPADDR} netmask ${NETMASK}
Testing
To test this custom configuration, I recommend disabling the firewall, my removing the executable permission bit from /etc/init.d/S45firewall and /etc/init.d/S41network just to prevent being locked out from the box in case problems arise.
Firewalling
I’ve also replaced the firewalling init script, /etc/init.d/S45firewall, with my own version. This allows for a fine-grained and thighter configuration.
Since the box will act as a routing firewall, and since it has 3 VLANs, I wanted to apply the following policy:
- Any traffic coming from or going to the administrative VLAN (VLAN2) is allowed:
This rule allows administering the box from a computer attached to the VLAN2, while blocking administrative access from other VLANs.
- Incoming ICMP Echo Requests and ICMP Time Exceeded control messages are allowed from any interface:
This rule allows certain ICMP control messages to reach the box. ICMP Echo Request is needed in order for the box to respond to
pingand ICMP Time Exceeded (TTL) so we don’t break the PMTU discovery algorithm. - Any other incoming traffic from the LAN is rejected:
This rule rejects any other traffic which does not match previous rules. Traffic is explicitly rejected, so we avoid having clients blocked waiting for an RST TCP segment.
- Any other incoming traffic from the WAN is dropped:
This rule silently drops any traffic coming from the WAN which does not match any previous rule. This will make external scan attacks much slower.
- Local DNS queries coming from the local box going to configured DNS servers are allowed:
This rule allows the local machine to resolve DNS queries sent against configured DNS servers (those configured in the
wan_dnsNVRAM variable). This is rarely needed, but theipkgcommand requires a working DNS name resolution. - HTTP traffic from the local machine to the WAN is allowed:
This rule allows upgrading and installing packages using the
ipkgcommand. - Outgoing ICMP Echo Requests and ICMP Time Exceeded control messages are allowed from any interface:
This rule allows certain ICMP control messages to depart from the box. ICMP Echo Request is needed in order for the box to invoke
pingand ICMP Time Exceeded (TTL) so we don’t break the PMTU discovery algorithm. - Forwarding SSH/NX traffic coming from WAN to the designated SSH/NX server in the LAN:
This rule allows accesing the SSH/NX traffic from the WAN. In addition, I apply SNAT to make IP datagrams appear to come from the firewall box since I have multiple DSL links.
- Forwarding HTTP and HTTP/S traffic coming from the LAN targeted to the WAN:
This rule allows using HTTP and HTTP/S services from the LAN.
- DNS queries coming from the LAN going to configured DNS servers are allowed:
This rule allows the machines in the LAN to resolve DNS queries sent against configured DNS servers (those configured in the
wan_dnsNVRAM variable). - Forwarding ICMP Echo Requests coming from the LAN to the WAN:
This allows pinging external hosts from the LAN. ICMP Time Exceeded, however, is not forwarded, since the firewall sits in the middle between the LAN and the WAN (and I do use SNAT and DNAT).
Here is the complete /etc/init.d/S45firewall script:
#!/bin/sh
IPTABLES=/usr/sbin/iptables
FW_INET_IFACE=$(nvram get wan_ifname)
FW_INET_IP=$(nvram get wan_ipaddr)
FW_PRIVATE_IFACE=$(nvram get lan_ifname)
FW_PRIVATE_IP=$(nvram get lan_ipaddr)
FW_ADM_IFACE=$(nvram get adm_ifname)
NX_IP=10.200.0.10
$IPTABLES -F
$IPTABLES -t nat -F
# Configure SNAT/DNAT/MASQUERADE
$IPTABLES -t nat -A PREROUTING -i ${FW_INET_IFACE} -p tcp \
-d ${FW_INET_IP} --dport 179 \
-j DNAT --to-destination ${NX_IP}:22
$IPTABLES -t nat -A POSTROUTING -o ${FW_PRIVATE_IFACE} -p tcp \
-d ${NX_IP} --dport 22 \
-j SNAT --to-source ${FW_PRIVATE_IP}
$IPTABLES -t nat -A POSTROUTING -o ${FW_INET_IFACE} -j MASQUERADE
# Configure input firewall filtering:
# Allow:
# - Traffic flowing from the loopback interface
# - Traffic coming from the administrative VLAN
# - ICMP Echo Request coming from WAN
# - ICMP Time Exceeded (TTL) coming from WAN
# - Traffic from an already established or related connection
# Block:
# - Any traffic coming from the WAN
# Reject:
# - Any other traffic coming from the LAN
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A INPUT -i ${FW_ADM_IFACE} -j ACCEPT
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
$IPTABLES -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
$IPTABLES -A INPUT -i ${FW_INET_IFACE} -j DROP
$IPTABLES -A INPUT -j REJECT
# Configure output firewall filtering:
# Allow:
# - Traffic flowing to the loopback interface
# - HTTP traffic
# - ICMP Echo Request going to WAN
# - ICMP Time Exceeded (TTL) going to WAN
# - DNS queries to configured WAN name servers
# - Traffic from an already established or related connection
# Reject:
# - Any other traffic
$IPTABLES -A OUTPUT -o lo -j ACCEPT
$IPTABLES -A OUTPUT -o ${FW_INET_IFACE} -p tcp -m tcp \
--dport 80 -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
$IPTABLES -A OUTPUT -p icmp --icmp-type time-exceeded -j ACCEPT
for ns in $(nvram get wan_dns); do
$IPTABLES -A OUTPUT -o ${FW_INET_IFACE} -p udp -m udp \
-d "$ns" --dport 53 -j ACCEPT
$IPTABLES -A OUTPUT -o ${FW_INET_IFACE} -p tcp -m tcp \
-d "$ns" --dport 53 -j ACCEPT
done
$IPTABLES -A OUTPUT -j REJECT
# Configure forward firewall filtering:
# Allow:
# - Incoming SSH/NX traffic -> the filtering takes place after the
# PREROUTING chain has been processed and, since DNAT has been already
# being performed, the traffic is filtered accordingly to its final
# destination (the SSH/NX server)
# - Outgoing DNS queries to configured WAN name servers
# - Outgoing HTTP and HTTP/S traffic
# - ICMP Echo Request coming from LAN going to WAN
# - Trafic from an already established or related connection
# Drop:
# - Any other traffic
$IPTABLES -A FORWARD -i ${FW_INET_IFACE} -o ${FW_PRIVATE_IFACE} -p tcp -m tcp \
-d ${NX_IP} --dport 22 -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -i ${FW_PRIVATE_IFACE} -o ${FW_INET_IFACE} -p tcp -m tcp \
--dport 80 -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -i ${FW_PRIVATE_IFACE} -o ${FW_INET_IFACE} -p tcp -m tcp \
--dport 443 -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -i ${FW_PRIVATE_IFACE} -o ${FW_INET_IFACE} \
-p icmp --icmp-type echo-request -j ACCEPT
for ns in $(nvram get wan_dns); do
$IPTABLES -A FORWARD -i ${FW_PRIVATE_IFACE} -o ${FW_INET_IFACE} \
-p udp -m udp -d "$ns" --dport 53 -j ACCEPT
$IPTABLES -A FORWARD -i ${FW_PRIVATE_IFACE} -o ${FW_INET_IFACE} \
-p tcp -m tcp -d "$ns" --dport 53 -j ACCEPT
done
$IPTABLES -A FORWARD -j DROP
Ubuntu title OpenType font
July 13th, 2006
QEMU and TUN/TAP networking
July 5th, 2006
Using TUN/TAP networking with QEMU grant guest machines access to some or all networks reachable by the host machine. This also allows accessing services offered by guests machines from any other host.
To be able to use TUN/TAP network, instead of directly configuring the physical Ethernet network device — my Realtek 8169 Gigabit Ethernet, which in my computer it’s named eth1 –, we need to reconfigure the network in order to get a bridge device, named br0, with the physical Ethernet eth1 device attached to it. We can achieve this by editing /etc/network/interfaces to look like this:
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
#auto eth1
#iface eth1 inet static
auto br0
iface br0 inet static
address a.b.c.d
netmask 255.255.255.128
gateway v.w.x.y
bridge_ports eth1
bridge_fd 1
bridge_hello 1
bridge_stp off
The helper script /etc/qemu-ifup, which QEMU uses to bring up a TAP network interface used by the guest and bind it to the existing bridge br0, should look like this:
#!/bin/sh echo "Executing /etc/qemu-ifup" echo "Bringing up $1 for bridged mode..." sudo /sbin/ifconfig $1 0.0.0.0 promisc up echo "Adding $1 to br0..." sudo /usr/sbin/brctl addif br0 $1 sleep 2
To allow running QEMU as an unprivileged user, we need to edit /etc/sudoers in order to grant access for running /sbin/ifconfig and /usr/sbin/brctl. It’s recommended to edit that file using visudo. The file should could look like this:
# Cmnd alias specification
Cmnd_Alias QEMU=/sbin/ifconfig, \\
/sbin/modprobe, \\
/usr/sbin/brctl
# Defaults
Defaults !lecture,tty_tickets,!fqdn,rootpw
# User privilege specification
root ALL=(ALL) ALL
# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL
# Grant access to Cmnd_Alias to user jdoe
jdoe ALL=NOPASSWD:QEMU
Now, we can launch qemu from the command line:
XLIB_SKIP_ARGB_VISUALS=1 \\ qemu -hda hda -cdrom *iso -boot d \\ -m 512 -localtime -net nic,vlan=0 \\ -net tap,ifname=tap0,script=/etc/qemu-ifup \\ -kernel-kqemu
Package management, repositories, metadata
June 6th, 2006
I found the following post from Pascal Bleser talking about repositories, metadata, packages, and so on. All this started due to the problems with package management in SUSE 10.1:
The generic and most appropriate term is “repository”.
Well, the repository is on the server-side, for example:
- http://ftp.gwdg.de/pub/linux/misc/suser-guru/rpm/10.1
Is a yast2 repository
- http://ftp.gwdg.de/pub/linux/misc/suser-guru/rpm/10.1/RPMS
Is an RPM-MD (/repomd/yum, see below) repository
- http://ftp.gwdg.de/pub/linux/suse/apt/SuSE/10.1-i386
Is an APT-RPM repository
The following terms are used by different package managers and are all references to repositories.
Such references usually contain information such as:
- the base URL, where to retrieve the metadata and the packages
- a name, but also additional information, depending on what the package manager is capable of handling.
- YaST2 calls them “installation sources”
- ZMD/rug calls them “catalogs”
- smart calls them “channels” (AFAICR, Red Carpet calls them “channels” as well)
- apt-rpm calls them “sources”
- yum calls them “repos” (repositories)
but they’re all the same thing: references to package repositories.
Package repositories are made of “metadata”.
That metadata contains various information about the RPM packages that
are available in a repository, such as:
- package name, version, release, target architecture, distribution
- summary, description, license, project website
- what it requires
- what it provides, and the list of files contained in the package
That metadata information is needed by package managers like libzypp,
ZMD/rug, apt-rpm, smart, yum, … to be able to compute how to perform
package installations, upgrades, removals (the requires/provides
information is particularly important here).There are different metadata formats:
- RPM-MD (RPM-MetaData), also called “repomd” (Repository MetaData), also called “yum” (because its the native format for the yum package manager)
- yast2
- apt-rpm (for RPM) and apt-deb (for DEB)
- Red Carpet (also called Open Carpet)
- RPM-HDL (RPM Header List)
- URPMI (for Mandriva’s package manager)
- slack, for Slackware’s “package manager” and maybe a few others.
So, unfortunately, there’s more or less a metadata format for every single package manager. It seems the NiH (*) syndrom has spread a lot amongst package manager developers.
(*) “Not invented Here”Nowadays, most package managers seem to head for RPM-MD support, which is more or less becoming a standard:
- YaST2 supports it in SUSE Linux 10.0
- libzypp supports it in SUSE Linux 10.1
- yum supports it, obviously, it’s the yum-specific format
![]()
- apt-rpm supports it too, since one or two releases (not the version shipped with SUSE Linux 10.1 though)
- smart supports it, of course
(more information about that below)
RPM-MD is represented in XML – actually, the repository metadata is stored in gzipped XML files, in a “repodata” subdirectory on the server (*), with the following files:
- repomd.xml: main repository file, very small, contains references to the others, as well as checksums and timestamps
- primary.xml.gz: contains the most important information: list of packages (with version, release, architecture), what it requires, size of the package, summary, description, etc….
- filelists.xml.gz: contains the list of files that are included in the packages
- other.xml.gz: not used by all package managers, it contains the changelog information of every package
(*) for an example:
http://ftp.gwdg.de/pub/linux/misc/suser-guru/rpm/10.1/RPMS/repodata/
Read here for more information on RPM-MD:
http://linux.duke.edu/projects/metadata/
smart is a notable exception, because it supports *all* of the formats
above (and it has no smart-specific format).When you add a smart “channel” (repository information), here are the
types you can use (excerpt from “smart channel –help”):
apt-deb – APT-DEB Repository
apt-rpm – APT-RPM Repository
deb-dir – DEB Directory
red-carpet – Red Carpet Channel
rpm-dir – RPM Directory
rpm-hdl – RPM Header List
rpm-md – RPM MetaData
slack-site – Slackware Repository
up2date-mirrors – Mirror Information (up2date format)
urpmi – URPMI Repository
yast2 – YaST2 Repository(note, I removed the *-sys channels, they represent the packages
currently installed in the RPM database (or DEB database on Debian, etc…))And yes, you can even mix them. In my list of channels for smart, I mix
yast2, rpm-md and apt-rpm repositories.smart is even independent of the package subsystem, as it works for RPM (SUSE/Redhat/Fedora/Mandriva), Deb (Debian/Ubuntu) and Slackware. So you could install a .deb Debian/Ubuntu package on SUSE Linux with smart, but it wouldn’t make any sense because it would be stored in a DEB package database… that knows nothing about the RPM database, etc… (so that usage is pretty pointless, and not the goal of smart anyway). Actually it’s interesting because you can use smart (unmodified) on RPM, Deb and Slackware based distributions.
Cyrus-IMAP and PAM interactions on x86_64
May 20th, 2006
In Red Hat Enterprise Linux ES 4.1 Update 3, both /etc/pam.d/imap and /etc/pam.d/pop contain hard-coded paths pointing to pam_stack.so, actually /lib/security/pam_stack.so. This causes problems on x86_64 since pam_stack.so is located under /lib64/security/pam_stack.so.
A workaround is to modify /etc/pam.d/imap and /etc/pam.d/pop to look like this:
#%PAM-1.0 auth required pam_stack.so service=system-auth account required pam_stack.so service=system-auth
I filled in a bug report against Red Hat Enterprise Linux 4:
saslauthd and testsaslauthd
May 20th, 2006
Care must be exercised when using testsaslauthd to check whether SASL authentication is working and saslauthd is configured to use PAM:
# cat /etc/sysconfig/saslauthd SOCKETDIR=/var/run/saslauthd MECH=pam FLAGS=
By default, testsaslauthd test whether the authentication process works by invoking authentication onto the imap service, unless the -s service is passed along in the command-line. PAM configuration for the imap service is stored in /etc/pam.d/imap. However, if cyrus-imapd is not installed, the file /etc/pam.d/imap won’t exist and thus any try to use testsaslauthd against the default imap service will fail:
# ls -l /etc/pam.d/imap ls: /etc/pam.d/imap: No such file or directory # testsaslauthd -u felipe.alfaro -p password 0: NO "authentication failed" # tail /var/log/messages May 20 16:36:47 mail2 saslauthd[2626]: do_auth : auth failure: [user=felipe.alfaro] [service=imap] [realm=] [mech=pam] [reason=PAM auth error # testsaslauthd -s login -u felipe.alfaro -p password 0: OK "Success.
User management using LDAP and libuser
May 18th, 2006
libuser is a collection of libraries and tools to manage users and groups under Linux or UNIX-like systems. libuser has several modules allowing to manage users and groups through different backends, like local (password and shadow) and LDAP (the LDAP backend has been somewhat unusable up to version 0.52).
The LDAP module, however, requires the user to supply a BIND_PW (password) for the BIND_DN (user) in order to authenticate against the LDAP directory server an perform the modifications. In automated deployment scenarios, it’s essential to be able to perform operations on to the LDAP directory server without asking the user for the password. Instead, the password used to authenticate against the LDAP directory server could be well stored in libuser’s configuration file, /etc/libuser.conf.
I’ve made a patch against libuser that implements a new configuration parameter for the LDAP module. This new parameter is named password, and specifies the password for the user binddn user.
Here is a sample of libuser’s configuration file, /etc/libuser.conf:
[defaults] # The default (/usr/lib*/libuser) is usually correct # moduledir = /your/custom/directory skeleton = /etc/skel mailspooldir = /var/mail modules = ldap create_modules = ldap crypt_style = md5 [userdefaults] LU_USERNAME = %n LU_UIDNUMBER = 10000 LU_GIDNUMBER = %u LU_HOMEDIRECTORY = /home/%n LU_LOGINSHELL = /bin/bash [groupdefaults] LU_GROUPNAME = %n LU_GIDNUMBER = 10000 [ldap] # Setting these is always necessary. server = ldap://directory.server.fqdn basedn = dc=example,dc=com # Setting these is rarely necessary, since it's usually correct. userBranch = ou=People groupBranch = ou=Groups # Set only if your administrative user uses simple bind operations to # connect to the server. binddn = cn=Directory Manager password = secret
The patched SRPM and diff patch can be obtained from here: libuser-0.52.5-1.el4.1
Fedora Core rescue and umount /mnt/sysimage
April 20th, 2006
Today, I was trying to resize a logical volume of one of my systems running Fedora Core 5, configured with two LVM volumes (one for the root filesystem and another one for swap) on top of a software RAID-0. Since the volume I wanted to shrink holds the root filesystem, I had to boot from the Fedora Core 5 rescue CD in order to reduce the filesystem (ext2online didn’t allow me to reduce the filesystem on the fly), then reducing the volume itself.
Thus, I booted from the Fedora Core 5 DVD by entering linux rescue at the syslinux prompt, then choosed English for both the system language and keyboard layout. Since I was lazy, and didn’t want to manually set up the RAID disks and search for LVM volumes, I told Anaconda to scan the system for a Linux installation and mount it read-only under /mnt/sysimage.
What I didn’t know is that Anaconda also spawns up /mnt/sysimage/usr/bin/bash as the shell (instead of /bin/bash which is the one I expected), appends /mnt/sysimage/bin:/mnt/sysimage/sbin:\ to
/mnt/sysimage/usr/bin:/mnt/sysimage/usr/sbin:\
/mnt/usr/X11R6/binPATH and appends /mnt/sysimage/lib:/mnt/sysimage/usr/lib to LD_LIBRARY_PATH. So, when I tried to umount /mnt/sysimage it failed with a Device or resource busy error message:
# umount /mnt/sysimage/boot # umount /mnt/sysimage/dev # umount /mnt/sysimage/selinux # umount /mnt/sysimage/sys # umount /mnt/sysimage/proc # umount /mnt/sysimage umount: Device or resource busy
The solution was easy, however:
# exec /bin/bash # umount /mnt/sysimage # echo $? 0