Get Chitika | Premium
| 1 comments ]

This article shows how you can do port-forwarding with rinetd on Debian Etch. rinetd allows you to forward ports from one system to another. This useful if you have moved your web sites to a new server with a different IP address. Of course, you have modified your DNS records, but it can take a few days until DNS changes become effective, and that is where rinetd comes into play. If clients still use the old DNS records, rinetd can redirect them to the new server. With rinetd, you do not have to fiddle with iptables rules.



I do not issue any guarantee that this will work for you!

1 Preliminary Note

In this example I'm trying to redirect HTTP traffic (port 80) from the IP address 192.168.0.101 to the IP address 192.168.0.100.

Please note that rinetd is not able to redirect FTP because FTP requires more than one socket.

2 Installing And Configuring rinetd

To install rinetd, we simply run

apt-get install rinetd

rinetd's configuration file is /etc/rinetd.conf. To forward HTTP traffic from 192.168.0.101 to 192.168.0.100, we add the line 192.168.0.101 80 192.168.0.100 80:

vi /etc/rinetd.conf

#
# this is the configuration file for rinetd, the internet redirection server
#
# you may specify global allow and deny rules here
# only ip addresses are matched, hostnames cannot be specified here
# the wildcards you may use are * and ?
#
# allow 192.168.2.*
# deny 192.168.2.1?


#
# forwarding rules come here
#
# you may specify allow and deny rules after a specific forwarding rule
# to apply to only that forwarding rule
#
# bindadress bindport connectaddress connectport
192.168.0.101 80 192.168.0.100 80

# logging information
logfile /var/log/rinetd.log

# uncomment the following line if you want web-server style logfile format
# logcommon

Then we restart rinetd:

/etc/init.d/rinetd restart

Now run

netstat -tap

and you should see that rinetd is listening on port 80 (www):

server2:~# netstat -tap
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 *:sunrpc *:* LISTEN 1956/portmap
tcp 0 0 server2.example.com:www *:* LISTEN 2485/rinetd
tcp 0 0 *:3025 *:* LISTEN 2347/rpc.statd
tcp 0 0 *:auth *:* LISTEN 2306/inetd
tcp 0 0 localhost.localdom:smtp *:* LISTEN 2294/exim4
tcp6 0 0 *:ssh *:* LISTEN 2326/sshd
tcp6 0 0 server2.example.com:ssh ::ffff:192.168.0.3:4776 ESTABLISHED2409/0
server2:~#

Now when you direct your browser to a web page on the IP address 192.168.0.101, it should receive that page from the server with the IP address 192.168.0.100.

Instead of specifiying the port numbers in /etc/rinetd.conf, you can also use the service names. The service names are stored in /etc/services, so when you open that file, you will see that the service for port 80 is named www on Debian.

grep 80 /etc/services

server2:~# grep 80 /etc/services
www 80/tcp http # WorldWideWeb HTTP
www 80/udp # HyperText Transfer Protocol

socks 1080/tcp # socks proxy server
socks 1080/udp
amanda 10080/tcp # amanda backup services
amanda 10080/udp
omirr 808/tcp omirrd # online mirror
omirr 808/udp omirrd
canna 5680/tcp # cannaserver
zope-ftp 8021/tcp # zope management by ftp
webcache 8080/tcp # WWW caching service
tproxy 8081/tcp # Transparent Proxy
omniorb 8088/tcp # OmniORB
omniorb 8088/udp
server2:~#

So you could use the following configuration in /etc/rinetd.conf, it has the same effect as the first one:

vi /etc/rinetd.conf

#
# this is the configuration file for rinetd, the internet redirection server
#
# you may specify global allow and deny rules here
# only ip addresses are matched, hostnames cannot be specified here
# the wildcards you may use are * and ?
#
# allow 192.168.2.*
# deny 192.168.2.1?


#
# forwarding rules come here
#
# you may specify allow and deny rules after a specific forwarding rule
# to apply to only that forwarding rule
#
# bindadress bindport connectaddress connectport
192.168.0.101 www 192.168.0.100 www

# logging information
logfile /var/log/rinetd.log

# uncomment the following line if you want web-server style logfile format
# logcommon

And to make rinetd listen on all IP addresses that are configured on the system where it is installed, we can use 0.0.0.0 as the bindaddress:

vi /etc/rinetd.conf

#
# this is the configuration file for rinetd, the internet redirection server
#
# you may specify global allow and deny rules here
# only ip addresses are matched, hostnames cannot be specified here
# the wildcards you may use are * and ?
#
# allow 192.168.2.*
# deny 192.168.2.1?


#
# forwarding rules come here
#
# you may specify allow and deny rules after a specific forwarding rule
# to apply to only that forwarding rule
#
# bindadress bindport connectaddress connectport
0.0.0.0 80 192.168.0.100 80

# logging information
logfile /var/log/rinetd.log

# uncomment the following line if you want web-server style logfile format
# logcommon

After you've restarted rinetd...

/etc/init.d/rinetd restart

... rinetd should now listen on all interfaces (*:www):

netstat -tap

server2:~# netstat -tap
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 *:sunrpc *:* LISTEN 1956/portmap
tcp 0 0 *:www *:* LISTEN 2503/rinetd
tcp 0 0 *:3025 *:* LISTEN 2347/rpc.statd
tcp 0 0 *:auth *:* LISTEN 2306/inetd
tcp 0 0 localhost.localdom:smtp *:* LISTEN 2294/exim4
tcp 0 0 server2.example.com:www 192.168.0.3:4798 TIME_WAIT -
tcp6 0 0 *:ssh *:* LISTEN 2326/sshd
tcp6 0 148 server2.example.com:ssh ::ffff:192.168.0.3:4776 ESTABLISHED2409/0
server2:~#

3 Links



Read More......
| 0 comments ]

This document describes how you can configure a Debian Etch system for IPv6 so that a) it can connect to other IPv6 hosts and b) other IPv6 hosts can connect to it. IPv6 should become more important in the future as recent estimates assume that there will be no more IPv4 addresses left by 2010 or 2011. Therefore it's time time to learn IPv6.

This document comes without warranty of any kind! I do not issue any guarantee that this will work for you!


1 Preliminary Note

In this tutorial I'm using a Debian server in a LAN (i.e., it uses a router to connect to the Internet) with the ethernet device eth0 and the IPv4 address 192.168.0.100. The router's public IP address at the time of this writing was 85.176.139.73. With IPv6, other systems can connect directly to the Debian system, regardless of the router and NAT. This tutorial will work for Debian systems that are connected directly to the Internet (i.e., no NAT, no router) as well.

To use IPv6, we will configure a tunnel that connects our IPv6 Debian system to IPv6 hardware on the other end (run by a so-called "tunnel broker") and thus to the IPv6 backbone. This tunnel is necessary because most ISPs don't support direct IPv6 connectivity, and it doesn't make sense to route IPv6 traffic over an IPv4 network because chances are that the next-hop router doesn't know what to do with this traffic.

There are multiple tunnel brokers that give you a tunnel and IPv6 addresses for free (e.g. http://tunnelbroker.net/, http://go6.net/4105/freenet.asp, http://www.sixxs.net/). These tunnel brokers are connected to the IPv6 backbone, and the tunnel connects your Debian Etch system to their IPv6 hardware and therefore to the IPv6 backbone.

2 Creating A Tunnel

Register with a tunnel broker - I'm using http://tunnelbroker.net/ as they are very fast - you can be up and running in a few minutes. Then log in on their web interface and create a tunnel ("Create Regular Tunnel" on the http://tunnelbroker.net/ web site). Fill in the IPv4 endpoint (this is the public IPv4 address of your Debian system - if it is behind a router, this is your router's public IPv4 address) and select a location close to you (these are the locations where the tunnel broker has POPs, i.e., connections to the IPv6 backbone):

Afterwards you will see a screen with the details of your tunnel.

These are the details for my test tunnel:

Server IPv4 address: 216.66.80.30
Server IPv6 address: 2001:0470:1f0a:cc0::1/64
Client IPv4 address: 85.176.139.73
Client IPv6 address: 2001:0470:1f0a:cc0::2/64

Please write down the Server IPv4 address (216.66.80.30), the Server IPv6 address (2001:0470:1f0a:cc0::1), and the Client IPv6 address (2001:0470:1f0a:cc0::2). We will need them in a moment.

3 Configuring The Debian System

Log in to your Debian system and take a look at the output of

ifconfig

server1:~# ifconfig
eth0 Link encap:Ethernet HWaddr 00:0C:29:A5:5B:93
inet addr:192.168.0.100 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fea5:5b93/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:71 errors:0 dropped:0 overruns:0 frame:0
TX packets:44 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:7789 (7.6 KiB) TX bytes:5809 (5.6 KiB)
Interrupt:169 Base address:0x1400

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:560 (560.0 b) TX bytes:560 (560.0 b)

server1:~#

Nothing special here, but the inet6 addr in the output means that the system is IPv6 capable.

Now we configure our new public IPv6 address and the tunnel as follows:

ifconfig sit0 up
ifconfig sit0 inet6 tunnel ::216.66.80.30 #(please replace the IPv4 address with the IPv4 address of the tunnel broker server that you've chosen in the previous step)
ifconfig sit1 up
ifconfig sit1 inet6 add 2001:0470:1f0a:cc0::2/64 #(please replace the IPv6 address with your own IPv6 address)
route -A inet6 add ::/0 dev sit1

That's it already. Take a look at

ifconfig

again, and you should see two new interfaces (sit0 and sit1) that are needed for our tunnel:

server1:~# ifconfig
eth0 Link encap:Ethernet HWaddr 00:0C:29:A5:5B:93
inet addr:192.168.0.100 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fea5:5b93/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:145 errors:0 dropped:0 overruns:0 frame:0
TX packets:163 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:12833 (12.5 KiB) TX bytes:19303 (18.8 KiB)
Interrupt:169 Base address:0x1400

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:560 (560.0 b) TX bytes:560 (560.0 b)

sit0 Link encap:IPv6-in-IPv4
inet6 addr: ::127.0.0.1/96 Scope:Unknown
inet6 addr: ::192.168.0.100/96 Scope:Compat
UP RUNNING NOARP MTU:1480 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)

sit1 Link encap:IPv6-in-IPv4
inet6 addr: 2001:470:1f0a:cc0::2/64 Scope:Global
inet6 addr: fe80::c0a8:64/64 Scope:Link
UP POINTOPOINT RUNNING NOARP MTU:1480 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)

server1:~#

Now we can test if we can ping the IPv6 address of the tunnel broker's server:

ping6 -c4 2001:0470:1f0a:cc0::1

server1:~# ping6 -c4 2001:0470:1f0a:cc0::1
PING 2001:0470:1f0a:cc0::1(2001:470:1f0a:cc0::1) 56 data bytes
64 bytes from 2001:470:1f0a:cc0::1: icmp_seq=1 ttl=64 time=16.8 ms
64 bytes from 2001:470:1f0a:cc0::1: icmp_seq=2 ttl=64 time=40.5 ms
64 bytes from 2001:470:1f0a:cc0::1: icmp_seq=3 ttl=64 time=37.5 ms
64 bytes from 2001:470:1f0a:cc0::1: icmp_seq=4 ttl=64 time=37.5 ms

--- 2001:0470:1f0a:cc0::1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3002ms
rtt min/avg/max/mdev = 16.880/33.135/40.550/9.466 ms
server1:~#

Looks good.

http://www.ipv6.org/v6-www.html has a list of IPv6 hosts. Let's pick one of them and test if we can ping it as well:

ping6 -c4 www.ipv6.uni-muenster.de

server1:~# ping6 -c4 www.ipv6.uni-muenster.de
PING www.ipv6.uni-muenster.de(tolot.ipv6.uni-muenster.de) 56 data bytes
64 bytes from tolot.ipv6.uni-muenster.de: icmp_seq=1 ttl=57 time=29.3 ms
64 bytes from tolot.ipv6.uni-muenster.de: icmp_seq=2 ttl=57 time=38.7 ms
64 bytes from tolot.ipv6.uni-muenster.de: icmp_seq=3 ttl=57 time=60.4 ms
64 bytes from tolot.ipv6.uni-muenster.de: icmp_seq=4 ttl=57 time=23.1 ms

--- www.ipv6.uni-muenster.de ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3002ms
rtt min/avg/max/mdev = 23.194/37.940/60.454/14.127 ms
server1:~#

Ok, pinging other hosts is working fine. Now let's see if our system can be pinged on our public IPv6 address as well. Go to http://www.berkom.blazing.de/tools/ping.cgi and fill in your public IPv6 address. If all goes well, the output should be similar to this one:

Congratulations, IPv6 is now working on your system!

If you don't want to configure the sit0 and sit1 interfaces manually after each reboot, you can create the file /etc/network/if-up.d/ipv6 as follows:

vi /etc/network/if-up.d/ipv6

#!/bin/sh

PATH=/sbin:/bin

ifconfig sit0 up
ifconfig sit0 inet6 tunnel ::216.66.80.30
ifconfig sit1 up
ifconfig sit1 inet6 add 2001:0470:1f0a:cc0::2/64
route -A inet6 add ::/0 dev sit1

(Replace the IPv4 and IPv6 addresses with your own values!)

Then make the file executable:

chmod 755 /etc/network/if-up.d/ipv6

Now whenever the system boots, it starts the sit0 and sit1 interfaces automatically.




Read More......
| 0 comments ]

phpsh is an interactive shell for php that features readline history, tab completion, quick access to documentation. It was developed at Facebook and ironically, is written mostly in python. This article explains how you can install/use it on a Debian Etch system.

This document comes without warranty of any kind! I do not issue any guarantee that this will work for you!

1 Installing phpsh

phpsh depends on PHP (4 or 5, 5 is recommended) and Python 2.4+, therefore we install PHP5 and Python as follows:

apt-get install php5-cli python

Afterwards we download and uncompress phpsh as follows:

wget http://www.phpsh.org/phpsh-latest.tgz
tar xvfz phpsh-latest.tgz

This creates the directory phpsh with the phpsh executable. Before we can run phpsh, we must make it executable:

cd phpsh
chmod 755 phpsh

2 Using phpsh

Now we can start the PHP shell simply by running

./phpsh

http://www.phpsh.org/readme.php shows how you can use the PHP shell. You can use tab to autocomplete function names, global variable names, constants, classes, and interfaces, and you can use the arrow keys to browse the command history. The equal sign at the beginning of a line will return the value of an expression.

Type

q

to leave the PHP shell.

Here's a sample output:

server1:~/phpsh# ./phpsh
I can't find a tags file for you. To enable tab completion in phpsh,
go to the root directory of your php code and run 'ctags -R',
(or whatever the analagous command is with your version of ctags,)
then run phpsh from that directory or a subdirectory of that directory.
Commandline: php -q /root/phpsh/phpsh.php
phpsh (c)2006 by Charlie Cheever and Dan Corson and Facebook, Inc.
type 'h' or 'help' to see instructions & features
New Feature: You can use the -c option to turn off coloring
php> = 2 + 3
5
php> $test = "This is a test.";
php> echo $test;
This is a test.
php> = array(array(1,2,3), array("a" => "b", "c" => "d", "e" => "f"), 'g', 'h')
Array
(
[0] => Array
(
[0] => 1
[1] => 2
[2] => 3
)

[1] => Array
(
[a] => b
[c] => d
[e] => f
)

[2] => g
[3] => h
)

php> $a = "abcdefg";
php> echo substr($a,0,3);
abc
php> q

server1:~/phpsh#




Read More......
| 0 comments ]

Security is based on three characteristics: prevention, protection and detection. Grsecurity is a patch for Linux kernel that allows you to increase each of these points.

This howto was performed on a Debian Lenny system. Thus some tools are Debian specific. However, tasks can be performed with other distro specific tools or even with universal tools (make).

Everything will done with root privileges. However, you can perform them with a limited account thanks to sudo and fake-kpkg tools.

1. Preliminary Note

To compile the kernel, you need to install some specific packages:

rom1:/root# aptitude install patch bin86 kernel-package build-essential

If you like to configure your kernel in graphical console mode (make menuconfig), you must install one more package:

rom1:/root# aptitude install libncurses5-dev

Check that iniramfs-tools (used to generated the init ramdisk) is installed (it should be):

rom1:/usr/src# dpkg -l initramfs*

Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Installed/Config-files/Unpacked/Failed-config/Half-installed
|/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad)
||/ Name Version Description
+++-==============-==============-============================================
ii initramfs-tool 0.85i tools for generating an initramfs
rom1:/usr/src#

Go to the source folder:

rom1:/root# cd /usr/src

Download the grsecurity patch and the

2.6.24.5

Linux vanilla kernel:

rom1:/usr/src# wget grsecurity.net/grsecurity-2.1.11-2.6.24.5-200804211829.patch.gz

rom1:/usr/src# wget eu.kernel.org/pub/linux/kernel/v2.6/linux-2.6.24.5.tar.gz

NB: you may need to configure wget in case you are using an HTTP proxy (which may use authentication). You need to edit /root/.wgetrc so it looks like this:

http_proxy=192.168.0.1
proxy-user=foo # Put this line if you need to authenticate against your proxy
proxy-passwd=bar # Put this line if you need to authenticate against your proxy

Decompress the archive of the kernel:

rom1:/usr/src# tar xzvf linux-2.6.24.5.tar.gz

Create a symbolic link on the new kernel folder to ease the following tasks:

rom1:/usr/src# ln -s linux-2.6.24.5 linux

Now, the environment is ready. Let's go hardening!

2. Patch the vanilla kernel

Move the grsecurity patch to the new directory:

rom1:/usr/src# mv grsecurity-2.1.11-2.6.24.5-200804211829.patch.gz linux/grsecurity-2.1.11-2.6.24.5-200804211829.patch.gz

Decompress and patch the source of the kernel:

rom1:/usr/src# cd linux

rom1:/usr/src/linux# gunzip <>

Now the patch is applied and the source of the kernel was modified. Let's configure the kernel to enable Grsecurity.

3. Configure the hardened kernel

In this example, we will configure the kernel using a console menu (make menuconfig). This is why we installed the libncurses5-dev package. However, you can configure in pure console mode (make config), or in GUI mode (make xconfig).

Grsecurity has predefined levels: low, medium, high. It can also be configured in custom level where you choose to enable or not option by option. See http://www.grsecurity.net/confighelp.php/ for more info on each option. In this HowTo, we will configure Grsecurity in High level.

rom1:/usr/src/linux# make menuconfig

Now, we will enable Grsecurity in the menu.

Go to Security options > Grsecurity > tick Grsecurity. Then, you can go to Security Level and tick High.

You can profit from configuring Grsecurity to optimise your kernel. Eg: On your server you probably don't need support for infrared, blutooth, probably neither wifi, ipx, X25, token ring, ATM, firewire, PCcard, joystick, mouse, sound....

4. Compile the hardened kernel

It is now time to compile your hardened kernel. First, just in case, clean up:

rom1:/usr/src/linux# make-kpkg clean

Launch compilation itself (this may take a while depending on your CPU power and RAM availability!!!):

rom1:/usr/src/linux# make-kpkg --initrd --append-to-version "grsec1.0" kernel_image

In case you are not using a Debian distro, you can compile the classic way with:

make mrproper
make menuconfig
make clean
make
make modules_install
mkinitramfs
make install

5. Install the hardened kernel

Your new kernel is now compiled and a .deb package file has been generated in the /usr/src folder. You need to install your kernel as any .deb package:

rom1:/usr/src# dpkg -i linux-image-2.6.24.5-grsec_grsec1.0_i386.deb

During the installation, an initrd image will be generated. This may take a while depending on your CPU power and RAM availability! You may also check that the new kernel image is really a kernel !

rom1:/usr/src# file vmlinuz-2.6.24.5-grsec
vmlinuz-2.6.24.5-grsec: Linux kernel x86 boot executable RO-rootFS, root_dev 0x801, swap_dev 0x1, Normal VGA

It is now time to restart your system with your new hardened kernel:

rom1:/usr/src/linux# shutdown -r now

Now that your system has restarted, you can check that your new kernel is running:

rom1:~# uname -r

2.6.24.5-grsec

6. Testing the hardened kernel

Except the fact that uname -r is saying your kernel is a grsec one, how do you know you are running a hardened kernel ? This is where we will use paxtest which will simulate an attack on the kernel and show if you are vulnerable or not. Download paxtest:

rom1:/tmp# wget http://www.grsecurity.net/~paxguy1/paxtest-0.9.7-pre5.tar.gz

Extract it:

rom1:/tmp# tar xzvf paxtest-0.9.7-pre5.tar.gz
rom1:/tmp# cd paxtest-0.9.7-pre5

Compile it (type make to have the list of targets):

rom1:/tmp/paxtest-0.9.7-pre5# make generic

Run it (there are 2 differents modes: kiddie and blackhat):

rom1:/tmp/paxtest-0.9.7-pre5# ./paxtest kiddie

NB: unless you are using high grsecurity level or custom level, you will have a vulnerable kernel. Indeed, you are only getting userland ASLR protection in a medium mode.

7. Links




Read More......
| 0 comments ]

vzdump is a backup and restore utility for OpenVZ VMs. This tutorial shows how you can use it to clone/back up/restore virtual machines with vzdump.

I do not issue any guarantee that this will work for you!

1 Preliminary Note

I'm using two OpenVZ servers in this tutorial:

  • server1.example.com: IP 192.168.0.100
  • server2.example.com: IP 192.168.0.101

(Both are using Debian Etch and are set up according to this tutorial: Installing And Using OpenVZ On Debian Etch - but it works with any other distribution as well.)

I'm running a virtual machine with the hostname test.example.com, the IP address 192.168.0.102 and the VEID 102 on server1.example.com, and I want to back up that machine and restore it on server2.example.com.

We can restore it on server2.example.com with no changes (e.g. same IP address and hostname), but in that case we must stop the VM on server1.example.com because otherwise the IP address and hostname would conflict; the second possibility is to restore it on server2.example.com, but change some parameters like the IP address and hostname with the vzctl set command - in this case we can run both VMs (the original one on server1.example.com and the clone on server2.example.com) at the same time. This is a great method to clone VMs.

2 Preparing The OpenVZ Servers

First we must install vzdump and rsync which is a dependency. On Debian, the command is as follows:

server1/server2:

apt-get install vzdump rsync

3 Creating A Backup Of A VM

(This chapter is for server1 only!)

On server1.example.com, I want to create a backup of my VM with the VEID 102. Take a look at

man vzdump

to learn how to use vzdump.

To back up all VMs on your server, you'd use something like

vzdump --compress --dumpdir /home/backup --stop --all

--compress means: compress the dump file (results in a .tgz).

--dumpdir specifies the directory in which you want to store the dump. If you don't specify a dumpdir, it defaults to /vz/dump or /var/lib/vz/dump (depends on your distribution).

--stop stops the VM, creates the backup, and starts it again afterwards. Your VM can be down a few minutes if you use --stop. A faster solution would be to use...

--suspend: it suspends the VM; the VM is then copied via rsync to a temporary directory. The VM gets resumed right afterwards so that it's down only a few seconds, and then the dump is created using the copy in the temporary directory. I recommend to use this one if you can't afford long downtimes.

You can as well leave out --stop and --suspend and dump a running VM. In most cases this makes no problem, but it is possible that the dump is inconsistent, so be warned!

--all creates a dump of all available VMs. If you want to dump only a specific VM, replace --all with the VEID of the VM.

To create a dump of our VM 102 in /home/backup and stop the VM during the backup, use

vzdump --compress --dumpdir /home/backup --stop 102

To create a dump in the default directory (/vz/dump or /var/lib/vz/dump), use

vzdump --compress --stop 102

The output could look as follows:

server1:/vz/dump# vzdump --compress --stop 102
INFO: starting backup for VPS 102 (/var/lib/vz/private/102)
INFO: starting first sync /var/lib/vz/private/102 to /var/lib/vz/dump/tmp9009
INFO: stopping vps
Stopping container ...
Container was stopped
Container is unmounted
INFO: final sync /var/lib/vz/private/102 to /var/lib/vz/dump/tmp9009
INFO: restarting vps
Starting container ...
Container is mounted
Adding IP address(es): 192.168.0.102
Setting CPU units: 1000
Configure meminfo: 65536
Set hostname: test.example.com
File resolv.conf was modified
Container start in progress...
INFO: vps is online again after 15 seconds
INFO: Creating archive '/var/lib/vz/dump/vzdump-102.tgz' (/var/lib/vz/dump/tmp9009/102)
Total bytes written: 340428800 (325MiB, 11MiB/s)
INFO: backup for VPS 102 finished successful (1.37 minutes)
server1:/vz/dump#

To not stop, but suspend the VM, use

vzdump --compress --suspend 102

This is a sample output:

server1:~# vzdump --compress --suspend 102
INFO: starting backup for VPS 102 (/var/lib/vz/private/102)
INFO: starting first sync /var/lib/vz/private/102 to /var/lib/vz/dump/tmp10842
INFO: suspend vps
Setting up checkpoint...
suspend...
get context...
Checkpointing completed succesfully
INFO: final sync /var/lib/vz/private/102 to /var/lib/vz/dump/tmp10842
INFO: resume vps
Resuming...
INFO: vps is online again after 4 seconds
INFO: Creating archive '/var/lib/vz/dump/vzdump-102.tgz' (/var/lib/vz/dump/tmp10842/102)
Total bytes written: 340428800 (325MiB, 24MiB/s)
INFO: backup for VPS 102 finished successful (1.57 minutes)
server1:~#

After the backup, take a look at the dump directory...

ls -l /vz/dump/

... and you should see a .tgz file:

server1:~# ls -l /vz/dump/
total 147864
-rw-r--r-- 1 root root 1170 2008-11-20 17:40 vzdump-102.log
-rw-r--r-- 1 root root 151249685 2008-11-20 17:40 vzdump-102.tgz
server1:~#

You can now copy the dump to the other OpenVZ server, e.g. with scp (this copies /vz/dump/vzdump-102.tgz to the /home directory on server2.example.com):

scp /vz/dump/vzdump-102.tgz root@192.168.0.101:/home

4 Restoring A VM

(This chapter is for server2 only!)

On server2.example.com, you can now restore the VM as follows...

vzdump --restore /home/vzdump-102.tgz 250

... where 250 is the new VEID of the restored VM - you can use any VEID that is unused on server2.example.com - you could even use 102 again if it is unused on server2.example.com.

If you don't want to modify the settings of the VM (e.g. IP address, hostname), you can start it now, but please make sure that the original VM is stopped on server1.example.com because otherwise the IP addresses conflict:

vzctl start 250

If you want to run both VMs (the original one and the clone) at the same time, you must change the IP address and hostname of the clone before you start it.

To set a new hostname, run sonething like this:

vzctl set 250 --hostname test2.example.com --save

To set a new IP address, we must first delete the original one...

vzctl set 250 --ipdel 192.168.0.102 --save

... and then set a new one:

vzctl set 250 --ipadd 192.168.0.250 --save

Afterwards we can start the clone:

vzctl start 250

5 Links



Read More......
| 0 comments ]

Version 1.0

Author: Mohsin Mirza

This short guide explains how you can build virt-df, virt-top, virt-mem and virt-ctrl from the sources on a Debian Lenny system. These tools are currently available for Fedora in binary format.

virt-top - "top"-like utility for showing stats of virtualized domains.

virt-df - "df" for virtual guests. Run this on the host/dom0 to find out how much disk space is used and available on all partitions of all the guests.


make ; make install



virt-mem are tools for monitoring virtual guest load, kernel messages, process lists and so on without needing to log in to the guest itself.

virt-ctrl is a graphical management app for virtual machines, modelled after Virtual Machine Manager.

Dependencies

apt-get install libvirt-ocaml-dev ocaml-findlib libextlib-ocaml-dev libextlib-ocaml-dev libxml-light-ocaml-dev ocaml-native-compilers camlp4 camlp4-extra libgettext-ocaml-dev libcsv-ocaml-dev cmigrep libcurses-ocaml-dev liblablgtk2-ocaml-dev libdbus-ocaml-dev build-essential automake autoconf

Download ocaml-bitstring:

wget http://bitstring.googlecode.com/files/ocaml-bitstring-2.0.0.tar.gz

Compile:

tar zxvf ocaml-bitstring-2.0.0.tar.gz ; cd ocaml-bitstring-2.0.0 ; ./configure ; make && make install

Sources:

mkdir virt ; cd virt ; wget http://et.redhat.com/~rjones/virt-ctrl/files/virt-ctrl-1.0.1.tar.gz http://et.redhat.com/~rjones/virt-mem/files/virt-mem-0.3.1.tar.gz http://et.redhat.com/~rjones/virt-df/files/virt-df-2.1.5.tar.gz http://et.redhat.com/~rjones/virt-top/files/virt-top-1.0.3.tar.gz

Compile

tar zxvf virt-df-2.1.5.tar.gz ; cd virt-df-2.1.5 ; ./configure ; make all ; make opt ; make install

tar zxvf virt-top-1.0.3.tar.gz ; cd virt-top-1.0.3 ; ./configure ; make all ; make opt ; make install

tar zxvf virt-ctrl-1.0.1.tar.gz ; cd virt-ctrl-1.0.1 ; ./configure ; make all ; make opt ; make install

tar zxvf virt-mem-0.3.1.tar.gz ; cd virt-mem-0.3.1 ; ./configure ;

Read More......
| 0 comments ]

GNU'Linux or Linux operating system is free which is very popular for computers.
The term Linux or GNU / Linux (GNU) digunakin also as a reference to keseluzuhan Linux distro (Linux distribution), which is included in other programs supporting the operating system. Sample programs are web servers, programming languages, database, display desktop (Desktop Environment) (such as GNOME and KDE), and office applications (office suite), such as OpenOffice.org, KOffice, AbiWord, Gnumeric.


Linux distributions that have experienced rapid growth in terms of popularity, so the more popular versions of UNIX systems that use license and paid (proprietary) and the free version of UNIX that was originally rival Microsoft Windows dominance in the few.
Linux supports a lot of computer hardware, and has been in various digunakin equipment from personal computers, and superkomputer system benam (embedded systee), such as mobile phone (Ponsel) and personal video recorder.
Initially, Linux is created, developed, and used by peminatnya only. Linux now has support from major corporations such as IBM and Hewlett-Packard. These observers think the success of information technology, this is because Linux does not depend on the vendor (vendor independence), a low operational cost, and compatibility of a high than proprietary versions of UNIX, and security factors and kestabilannya compared with Microsoft Windows. The characteristics of this evidence is also a top model of the development benefits of open source software (opensource software).


Read More......
| 0 comments ]

This guide explains how to set up an NFS server and an NFS client on Debian Lenny. NFS stands for Network File System; through NFS, a client can access (read, write) a remote share on an NFS server as if it was on the local hard disk.

I do not issue any guarantee that this will work for you!

1 Preliminary Note



I'm using two Debian systems here:

* NFS Server: server.example.com, IP address: 192.168.0.100
* NFS Client: client.example.com, IP address: 192.168.0.101




2 Installing NFS



server:

On the NFS server we run:

apt-get install nfs-kernel-server nfs-common portmap

client:

On the client we can install NFS as follows:

apt-get install nfs-common portmap

3 Exporting Directories On The Server



server:

I'd like to make the directories /home and /var/nfs accessible to the client; therefore we must "export" them on the server.

When a client accesses an NFS share, this normally happens as the user nobody. Usually the /home directory isn't owned by nobody (and I don't recommend to change its ownership to nobody!), and because we want to read and write on /home, we tell NFS that accesses should be made as root (if our /home share was read-only, this wouldn't be necessary). The /var/nfs directory doesn't exist, so we can create it and change its ownership to nobody and nogroup:

mkdir /var/nfs
chown nobody:nogroup /var/nfs

Now we must modify /etc/exports where we "export" our NFS shares. We specify /home and /var/nfs as NFS shares and tell NFS to make accesses to /home as root (to learn more about /etc/exports, its format and available options, take a look at

man 5 exports

)

vi /etc/exports


# /etc/exports: the access control list for filesystems which may be exported
# to NFS clients. See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4 gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check)
#
/home 192.168.0.101(rw,sync,no_root_squash,no_subtree_check)
/var/nfs 192.168.0.101(rw,sync,no_subtree_check)



(The no_root_squash option makes that /home will be accessed as root.)

Whenever we modify /etc/exports, we must run

exportfs -a

afterwards to make the changes effective.

4 Mounting The NFS Shares On The Client



client:

First we create the directories where we want to mount the NFS shares, e.g.:

mkdir -p /mnt/nfs/home
mkdir -p /mnt/nfs/var/nfs

Afterwards, we can mount them as follows:

mount 192.168.0.100:/home /mnt/nfs/home
mount 192.168.0.100:/var/nfs /mnt/nfs/var/nfs

You should now see the two NFS shares in the outputs of

df -h

client:~# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg0-root 19G 676M 17G 4% /
tmpfs 253M 0 253M 0% /lib/init/rw
udev 10M 80K 10M 1% /dev
tmpfs 253M 0 253M 0% /dev/shm
/dev/sda1 471M 20M 427M 5% /boot
192.168.0.100:/home 29G 684M 27G 3% /mnt/nfs/home
192.168.0.100:/var/nfs
29G 684M 27G 3% /mnt/nfs/var/nfs
client:~#

and

mount

client:~# mount
/dev/mapper/vg0-root on / type ext3 (rw,errors=remount-ro)
tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
udev on /dev type tmpfs (rw,mode=0755)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620)
/dev/sda1 on /boot type ext3 (rw)
192.168.0.100:/home on /mnt/nfs/home type nfs (rw,addr=192.168.0.100)
192.168.0.100:/var/nfs on /mnt/nfs/var/nfs type nfs (rw,addr=192.168.0.100)
client:~#

5 Testing



On the client, you can now try to create test files on the NFS shares:

client:

touch /mnt/nfs/home/test.txt
touch /mnt/nfs/var/nfs/test.txt

Now go to the server and check if you can see both test files:

server:

ls -l /home/

server:~# ls -l /home/
total 4
drwxr-xr-x 2 administrator administrator 4096 2009-02-16 13:18 administrator
-rw-r--r-- 1 root root 0 2009-03-12 17:08 test.txt
server:~#

ls -l /var/nfs

server:~# ls -l /var/nfs
total 0
-rw-r--r-- 1 nobody nogroup 0 2009-03-12 17:08 test.txt
server:~#

(Please note the different ownerships of the test files: the /home NFS share gets accessed as root, therefore /home/test.txt is owned by root; the /var/nfs share gets accessed as nobody, therefore /var/nfs/test.txt is owned by nobody.)

6 Mounting NFS Shares At Boot Time



Instead of mounting the NFS shares manually on the client, you could modify /etc/fstab so that the NFS shares get mounted automatically when the client boots.

client:

Open /etc/fstab and append the following lines:

vi /etc/fstab


[...]
192.168.0.100:/home /mnt/nfs/home nfs rw,sync,hard,intr 0 0
192.168.0.100:/var/nfs /mnt/nfs/var/nfs nfs rw,sync,hard,intr 0 0




Instead of rw,sync,hard,intr you can use different mount options. To learn more about available options, take a look at

man nfs

To test if your modified /etc/fstab is working, reboot the client:

reboot

After the reboot, you should find the two NFS shares in the outputs of

df -h

client:~# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg0-root 19G 676M 17G 4% /
tmpfs 253M 0 253M 0% /lib/init/rw
udev 10M 80K 10M 1% /dev
tmpfs 253M 0 253M 0% /dev/shm
/dev/sda1 471M 20M 427M 5% /boot
192.168.0.100:/home 29G 684M 27G 3% /mnt/nfs/home
192.168.0.100:/var/nfs
29G 684M 27G 3% /mnt/nfs/var/nfs
client:~#

and

mount

client:~# mount
/dev/mapper/vg0-root on / type ext3 (rw,errors=remount-ro)
tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
udev on /dev type tmpfs (rw,mode=0755)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620)
/dev/sda1 on /boot type ext3 (rw)
192.168.0.100:/home on /mnt/nfs/home type nfs (rw,sync,hard,intr,addr=192.168.0.100)
192.168.0.100:/var/nfs on /mnt/nfs/var/nfs type nfs (rw,sync,hard,intr,addr=192.168.0.100)
client:~#

7 Links



Read More......
| 0 comments ]

Do you often need to reconnect due to download purposes or forward ports manually because some applications don't support it natively? Then this is the right thing for you! This howto covers a Perl script allowing you to administrate your gateway device via UPnP. You can reconnect, add and remove port forwarding entries and many more.

This Perl script allows you to do the following things:

* Trigger a reconnect
* Print all information your gateway offers
* Add a port forwarding entry
* Remove a port forwarding entry
* Print a port forwarding entry
* Print a list of all port forwarding entries
* Remove all port forwarding entries
* Enable or disable internet access globally


Installation

If you want to give it a try, follow these steps to install the script.

1. Copy the script to a file

You can find the script at the bottom of this article. Open your favorite editor and paste the script. Save it to ~/igdctl.pl.

Make the script executable by executing this command:

chmod +x ./igdctl.pl
2. Install a perl module
This script needs a perl module called Net::UPnP to work correctly. Run the following command in a terminal:

sudo apt-get install -y libnet-upnp-perl

This works only with DEB based systems. For RPM based systems you need a different installation command.

Triggering a reconnect

If you want your DSL router to get a new IP address just execute following command:

./igdctl.pl -r

Explanation: The script automaticly looks for an internet gateway device. -r tells the script to send a ForceTermination signal to the gateway.

Print information

You can print all information the gateway offers via UPnP. Use the following command:

./igdctl.pl -p

Explanation: -p tells the script to call some information returning procedures the device offers.

Adding a port forwarding entry

This procedure is needed if you want to use a program which don't support port forwarding via UPnP or NAT natively. Of course you could setup the port forwarding via the gateway's web interface, but the way described here is more comfortable.

The syntax is quite easy:

./igdctl.pl -a -e PORT -i PORT -E REMOTE -I CLIENT -P [TCP|UDP]

Explanation: -a tells the script to add a port mapping entry. -e tells the external port number and -i the internal one. In most cases the port numbers are equivalent. -E tells the remote host. This parameter is optional – in most cases it is left out. -I tells the client address. -P tells the protocol which can be TCP or UDP.

./igdctl.pl -a -e 4332 -i 4332 -I 192.168.0.5 -P TCP

Explanation: This command will setup a TCP port forwarding from the external port 4332 to the internal port 4332 of the client 192.168.0.5.

Removing a port forwarding entry

If you want to remove a port forwarding entry you previously added you can use the remove procedure.

The syntax is as easy as the one above:

./igdctl.pl -R -e PORT -E REMOTE -P [TCP/UDP]

Explanation: span class="system">-R tells the script to remove a previously added port mapping entry. -e tells the external port number. You don't have to specify the internal port number. -E tells the remote host. This parameter is optional. -P tells the protocol which can be TCP or UDP.

./igdctl.pl -R -e 4332 -P TCP

Explanation: This command will remove the previously added port mapping entry (see above).

Printinig a port forwarding entry

You can print information about a port forwarding entry by external port number, remote host and protocol.

The syntax is almost equal to the remove syntax:

./igdctl.pl -g -e PORT -E REMOTE -P [TCP/UDP]

Explanation: span class="system">-g tells the script to print information about a previously added port mapping entry. -e tells the external port number. -E tells the remote host. This parameter is optional. -P tells the protocol.

./igdctl.pl -g -e 4332 -P TCP

Explanation: This command will print the previously added port mapping entry (see above).

Printing a list of all port forwarding entries

If you want to get an overview of all ports being forwarded to clients, use this procedure.

./igdctl.pl -l -I CLIENT

Explanation: -l-I tells the client address. This is optional. Use this if you only want to print entries belonging to a specific client.

./igdctl.pl -l -I 192.168.0.5

Explanation: This will print out all port forwarding entries by 192.168.0.5

Removing all port forwarding entries at once

Quite useful if you want to remove all port forwarding entries globally or by a specific client.

./igdctl.pl -c -I CLIENT

Explanation: -c-I tells the client address. This is optional. Use this if you only want to remove entries belonging to a specific client.

./igdctl.pl -c -I 192.168.0.5

Explanation: This will remove all port forwarding entries by 192.168.0.5

Enabling or disabling internet access globally

You can enable or disable internet access globally if your gateway manufacturer has implemented this functionality.

WARNING: This functionality is almost unimplemented. Don't worry if you get an error.

./igdctl.pl [--enable|--disable]

Explanation: I think the syntax is self-explaining. --enable or --disable tells the script to enable or disable internet access globally.

Listings
igdctl.pl

#!/usr/bin/perl
#########################################################################################
#
# igdctl -:- Internet gateway device administration tool written in perl
#
# VERSION: 0.1
# AUTHOR: Vincent Wochnik
# EMAIL: v.wochnik@yahoo.com
# WWW: ubuntu.blogetery.com
# COPYRIGHT: (c) by Vincent Wochnik 2009
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
#########################################################################################
use strict;
use Getopt::Long;
use Net::UPnP::Device;
use Net::UPnP::ControlPoint;
## allow bundling of command line options
Getopt::Long::Configure('bundling');
##
## PARSE COMMAND LINE OPTIONS
##
my $help = 0;
my $verbose = 0;
my $action_print = 0;
my $action_enable = 0;
my $action_disable = 0;
my $action_reconnect = 0;
my $action_add_port = 0;
my $action_get_port = 0;
my $action_remove_port = 0;
my $action_list_ports = 0;
my $action_clear_ports = 0;
my $devnum = -1;
my $external_ip = '';
my $external_port = '';
my $internal_ip = '';
my $internal_port = '';
my $protocol = '';
my $duration = '';
my $active = 1; ## flag is set by default
if (!GetOptions('h|help', => \$help,
'v|verbose', => \$verbose,
'p|print' => \$action_print, ## print statistics
'r|reconnect' => \$action_reconnect, ## reconnect
'enable' => \$action_enable, ## enable internet access
'disable' => \$action_disable, ## disable internet access
'a|add-port' => \$action_add_port, ## add port mapping
'g|get-port' => \$action_get_port, ## get a port by external host, ip and protocol
'R|remove-port' => \$action_remove_port, ## remove port mapping
'c|clear-ports' => \$action_clear_ports, ## clear port mapping list
'l|list-ports' => \$action_list_ports, ## list port mappings
'd|device=i' => \$devnum, ## device number
'E|external-ip=s' => \$external_ip, ## external ip address
'e|external-port=i' => \$external_port, ## external port
'I|internal-ip=s' => \$internal_ip, ## client ip address
'i|internal-port=i' => \$internal_port, ## internal port
'P|protocol=s' => \$protocol, ## protocol (TCP/UDP
'D|duration=i' => \$duration, ## expiration time
'A|active=i' => \$active)) { ## active flag
$help = 1;
}
if ($action_print+$action_enable+$action_disable+$action_reconnect+$action_add_port+$action_get_port+$action_remove_port+$action_clear_ports+$action_list_ports > 1) {
## No multiple action parameters!!!
$help = 1;
} elsif ($action_print+$action_enable+$action_disable+$action_reconnect+$action_add_port+$action_get_port+$action_remove_port+$action_clear_ports+$action_list_ports == 0) {
## No action parameter found!!!
$help = 1;
} elsif ($action_print+$action_enable+$action_disable+$action_reconnect == 1) {
## Some action parameters don't require additional parameters
if (($external_ip) || ($external_port) || ($internal_ip) || ($internal_port) || ($duration)) {
$help = 1;
}
} elsif ($action_add_port+$action_get_port+$action_remove_port+$action_clear_ports+$action_list_ports == 1) {
## Check if all parameters are valid
if (
((($action_add_port) || ((($action_clear_ports) || ($action_list_ports)) && ($internal_ip))) && ($internal_ip !~ m/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/)) ||
((($action_add_port) || ($action_remove_port) || ($action_get_port)) && ($external_ip) && ($external_ip !~ m/^[0-9*]{1,3}\.[0-9*]{1,3}\.[0-9*]{1,3}\.[0-9*]{1,3}$/)) ||
(($action_add_port) && (($internal_port <> 65535))) ||
((($action_add_port) || ($action_remove_port) || ($action_get_port)) && (($external_port <> 65535))) ||
(($action_add_port) && (($duration) && ($duration < help =" 1;"> and exit 2;
}
## scanning for devices
print STDOUT "Scanning for devices ...\n" if $verbose;
my @devices = get_igd_devices();
my $devcount = length(@devices);
## error handling
print STDERR "No device found.\n\n" and exit 1 if (!@devices);
## if there is only one device, auto-choose
$devnum = 0 if ($devcount == 1);
## if verbose or device number invalid
if (($verbose) || ($devnum <>= $devcount)) {
printf STDOUT 'Found %d ', $devcount;
print STDOUT "device.\n\n" if ($devcount == 1);
print STDOUT "devices.\n\n" if ($devcount != 1);
}
## print list and ask the user if no device number is given per command argument
if (($devnum <>= $devcount)) {
## print device list
list_devices(@devices);
## user choice
while (($devnum !~ m/^[0-9]+$/) || ($devnum >= $devcount)) {
print("Please select a device.\nDevice: ");
chomp($devnum = );
print STDOUT "Invalid choice. Try again!\n" if (($devnum <>= $devcount));
print STDOUT "\n";
}
}
## Get chosen device
my $device = @devices[$devnum];
my $service;
## get service handler
if ($action_enable+$action_disable+$action_print) {
## Get WANIPCommonInterfaceConfig service
$service = $device->getservicebyname("urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1");
print STDERR "WANCommonInterfaceConfig service not avaleble.\n\n" and exit 1 if (!$service);
} else {##if ($action_reconnect+$action_add_port+$action_get_port+$action_remove_port+$action_clear_ports+$action_list_ports)
## Get WANIPConnection service
$service = $device->getservicebyname("urn:schemas-upnp-org:service:WANIPConnection:1");
print STDERR "WANCommonInterfaceConfig service not avaleble.\n\n" and exit 1 if (!$service);
}
if ($action_print) {
my $res, my $out_args, my $out="";
## Get internet enabled
print STDOUT "Trying to get internet access state ...\n" if $verbose;
$res = $service->postaction("GetEnabledForInternet");
if ($res->getstatuscode() != 200) {
print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
} else {
print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
$out_args = $res->getargumentlist();
if ($out_args->{'NewEnabledForInternet'}) {
$out .= sprintf('Internet access : enabled'."\n");
} else {
$out .= sprintf('Internet access : disabled'."\n");
}
}
## Get connection properties ...
print STDOUT "Trying to get connection properties ...\n" if $verbose;
$res = $service->postaction("GetCommonLinkProperties");
if ($res->getstatuscode() != 200) {
print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
} else {
print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
$out_args = $res->getargumentlist();
$out .= sprintf('WAN access type : %s'."\n", $out_args->{'NewWANAccessType'});
$out .= sprintf('Maximum upstream rate : %s bps'."\n", $out_args->{'NewLayer1UpstreamMaxBitRate'});
$out .= sprintf('Maximum downstream rate : %s bps'."\n", $out_args->{'NewLayer1DownstreamMaxBitRate'});
$out .= sprintf('Physical link state : %s'."\n", $out_args->{'NewPhysicalLinkStatus'});
}
## Get wan access provider
print STDOUT "Trying to get WAN access provider ...\n" if $verbose;
$res = $service->postaction("GetWANAccessProvider");
if ($res->getstatuscode() != 200) {
print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
} else {
print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
$out_args = $res->getargumentlist();
$out .= sprintf('WAN access provider : %s'."\n", $out_args->{'NewWANAccessProvider'});
}
## Get maximum number of active connections
print STDOUT "Trying to get maximum number of active connections ...\n" if $verbose;
$res = $service->postaction("GetMaximumActiveConnections");
if ($res->getstatuscode() != 200) {
print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
} else {
print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
$out_args = $res->getargumentlist();
$out .= sprintf('Max. number of active connections : %d'."\n", $out_args->{'MaximumActiveConnections'});
}
## Get total bytes sent
print STDOUT "Trying to get total number of bytes sent ...\n" if $verbose;
$res = $service->postaction("GetTotalBytesSent");
if ($res->getstatuscode() != 200) {
print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
} else {
print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
$out_args = $res->getargumentlist();
$out .= sprintf('Total bytes sent : %s'."\n", readable_size($out_args->{'NewTotalBytesSent'}));
}
## Get total packets sent
print STDOUT "Trying to get total number of packets sent ...\n" if $verbose;
$res = $service->postaction("GetTotalPacketsSent");
if ($res->getstatuscode() != 200) {
print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
} else {
print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
$out_args = $res->getargumentlist();
$out .= sprintf('Total packets sent : %d'."\n", $out_args->{'NewTotalPacketsReceived'});
}
## Get total bytes received
print STDOUT "Trying to get total number of bytes received ...\n" if $verbose;
$res = $service->postaction("GetTotalBytesReceived");
if ($res->getstatuscode() != 200) {
print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
} else {
print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
$out_args = $res->getargumentlist();
$out .= sprintf('Total bytes received : %s'."\n", readable_size($out_args->{'NewTotalBytesReceived'}));
}
## Get total packets received
print STDOUT "Trying to get total number of packets received ...\n" if $verbose;
$res = $service->postaction("GetTotalPacketsReceived");
if ($res->getstatuscode() != 200) {
print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
} else {
print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
$out_args = $res->getargumentlist();
$out .= sprintf('Total packets received : %d'."\n", $out_args->{'NewTotalPacketsReceived'});
}
print STDOUT $out."\n" and exit 0 if $out; ## print information
print STDERR "Nothing to print out.\n" and exit 1; ## otherwise print an error
} elsif ($action_enable) { ## OK <-- based on Documentation my $res, my %in_args, my $success=1; %in_args = ('NewEnabledForInternet' => '1');
## Enable internet access ...
print STDOUT "Trying to enable internet access ...\n" if $verbose;
$res = $service->postaction("SetEnabledForInternet", \%in_args);
## error handling
if ($res->getstatuscode() == 401) {
print STDERR "Operation not supported. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$success = 0;
} elsif ($res->getstatuscode() != 200) {
print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$success = 0;
} else {
print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
}
print STDOUT "Command successful.\n" and exit 0 if $success;
print STDERR "Command failed.\n" and exit 1;
} elsif ($action_disable) { ## OK <-- based on Documentation my $res, my %in_args, my $success=1; %in_args = ('NewEnabledForInternet' => '0');
## Disable internet access ...
print STDOUT "Trying to disable internet access ...\n" if $verbose;
$res = $service->postaction("SetEnabledForInternet", \%in_args);
## error handling
if ($res->getstatuscode() == 401) {
print STDERR "Operation not supported. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$success = 0;
} elsif ($res->getstatuscode() != 200) {
print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$success = 0;
} else {
print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
}
print STDOUT "Command successful.\n" and exit 0 if $success;
print STDERR "Command failed.\n" and exit 1;
} elsif ($action_reconnect) { ## OK <-- based on Documentation my $res, my $success=1; ## Force termination ... print STDOUT "Trying to terminate WANIPConnection ...\n" if $verbose; $res = $service->postaction("ForceTermination");
## error handling
if ($res->getstatuscode() == 501) {
print STDERR "Action failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$success = 0;
} elsif ($res->getstatuscode() == 710) {
print STDERR "Invalid connection type. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$success = 0;
} elsif ($res->getstatuscode() == 702) {
print STDERR "Disconnect in progress. (WARNING ".$res->getstatuscode().")\n\n" if $verbose;
} elsif ($res->getstatuscode() != 200) {
print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$success = 0;
} else {
print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
}
print STDERR "Command failed.\n" and exit 1 if (!$success);
## Requesting new connection ...
print STDOUT "Requesting new connection ...\n" if $verbose;
$res = $service->postaction("RequestConnection");
## error handling
if ($res->getstatuscode() == 704) {
print STDERR "Connection setup failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$success = 0;
} elsif ($res->getstatuscode() == 708) {
print STDERR "Invalid Layer2 address. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$success = 0;
} elsif ($res->getstatuscode() == 709) {
print STDERR "Internet access disabled. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$success = 0;
} elsif ($res->getstatuscode() == 710) {
print STDERR "Invalid connection type. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$success = 0;
} elsif ($res->getstatuscode() == 705) {
print STDERR "Connection setup in progress. (WARNING ".$res->getstatuscode().")\n\n" if $verbose;
} elsif ($res->getstatuscode() != 200) {
print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$success = 0;
} else {
print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
}
print STDOUT "Command successful.\n" and exit 0 if $success;
print STDERR "Command failed.\n" and exit 1;
} elsif ($action_add_port) {
my $res, my %in_args, my $success=1;
%in_args = ('NewRemoteHost' => $external_ip,
'NewExternalPort' => $external_port,
'NewProtocol' => $protocol,
'NewInternalPort' => $internal_port,
'NewInternalClient' => $internal_ip,
'NewEnabled' => $active,
'NewPortMappingDescription' => 'mapped by '.__FILE__,
'NewLeaseDuration' => $duration);
## trying to add port mapping entry
print STDOUT "Trying to add a port mapping entry ...\n" if $verbose;
$res = $service->postaction("AddPortMapping", \%in_args);
## error handling
if ($res->getstatuscode() == 402) {
print STDERR "Invalid args. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$success = 0;
} elsif ($res->getstatuscode() == 715) {
print STDERR "Wildcard not allowed in remote host address. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$success = 0;
} elsif ($res->getstatuscode() == 716) {
print STDERR "Wildcard not allowed in external port. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$success = 0;
} elsif ($res->getstatuscode() == 718) {
print STDERR "Conflicting with another mapping entry. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$success = 0;
} elsif ($res->getstatuscode() != 200) {
print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$success = 0;
} else {
print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
}
print STDOUT "Command successful.\n" and exit 0 if $success;
print STDERR "Command failed.\n" and exit 1;
} elsif ($action_remove_port) {
my $res, my %in_args, my $success=1;
%in_args = ('NewRemoteHost' => $external_ip,
'NewExternalPort' => $external_port,
'NewProtocol' => $protocol);
## remove port mapping entry
print STDOUT "Trying to remove a port mapping entry matching specified criteria ...\n" if $verbose;
$res = $service->postaction("DeletePortMapping", \%in_args);
## error handling
if ($res->getstatuscode() == 714) {
print STDERR "Entry not found. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
} elsif ($res->getstatuscode() != 200) {
print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$success = 0;
} else {
print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
}
print STDOUT "Command successful.\n" and exit 0 if $success;
print STDERR "Command failed.\n" and exit 1;
} elsif ($action_get_port) {
my $res, my %in_args, my $out_args, my $out;
%in_args = ('NewRemoteHost' => $external_ip,
'NewExternalPort' => $external_port,
'NewProtocol' => $protocol);
## print port mapping entry
print STDOUT "Trying to print a port mapping entry matching specified criteria ...\n" if $verbose;
$res = $service->postaction("GetSpecificPortMappingEntry", \%in_args);
## error handling
if ($res->getstatuscode() == 714) {
print STDERR "Entry not found. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
} elsif ($res->getstatuscode() != 200) {
print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
} else {
print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
$out_args = $res->getargumentlist();
$out = sprintf('%6s %15s %13s %15s %13s %10s'."\n", 'ACTIVE', 'REMOTE HOST', 'EXTERNAL PORT', 'CLIENT HOST', 'INTERNAL PORT', 'LEASE TIME') if (!$out);
if ($external_ip) {
$out .= sprintf('%6s %15s %13s %15s %13s %10s'."\n", $out_args->{'NewEnabled'}, $external_ip, $external_port, $out_args->{'NewInternalClient'}, $out_args->{'NewInternalPort'}, $out_args->{'NewLeaseDuration'});
} else {
$out .= sprintf('%6s %15s %13s %15s %13s %10s'."\n", $out_args->{'NewEnabled'}, '*', $external_port, $out_args->{'NewInternalClient'}, $out_args->{'NewInternalPort'}, $out_args->{'NewLeaseDuration'});
}
}
print STDOUT $out."\n" and exit 0 if $out; ## print information
print STDERR "Nothing to print out.\n" and exit 1; ## otherwise print an error
} elsif ($action_list_ports) {
my $res, my %in_args, my $out_args, my $i=0, my $out="";
while ($i >= 0) {
%in_args = ('NewPortMappingIndex' => $i);
## search port mapping entry
print STDOUT "Trying to search port mapping entry ...\n" if $verbose;
$res = $service->postaction("GetGenericPortMappingEntry", \%in_args);
## error handling
if ($res->getstatuscode() != 200) {
print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$i = -1; ## stop loop - there are no more entries
} else {
print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
$out_args = $res->getargumentlist();
if ((!$internal_ip) || ($out_args->{'NewInternalClient'} =~ m/^($internal_ip)$/)) {
$out = sprintf('%6s %15s %13s %15s %13s %10s'."\n", 'ACTIVE', 'REMOTE HOST', 'EXTERNAL PORT', 'CLIENT HOST', 'INTERNAL PORT', 'LEASE TIME') if (!$out);
if ($out_args->{'NewRemoteHost'}) {
$out .= sprintf('%6s %15s %13s %15s %13s %10s'."\n", $out_args->{'NewEnabled'}, $out_args->{'NewRemoteHost'}, $out_args->{'NewExternalPort'}, $out_args->{'NewInternalClient'}, $out_args->{'NewInternalPort'}, $out_args->{'NewLeaseDuration'});
} else {
$out .= sprintf('%6s %15s %13s %15s %13s %10s'."\n", $out_args->{'NewEnabled'}, '*', $out_args->{'NewExternalPort'}, $out_args->{'NewInternalClient'}, $out_args->{'NewInternalPort'}, $out_args->{'NewLeaseDuration'});
}
}
$i++;
}
}
print STDOUT $out."\n" and exit 0 if $out; ## print information
print STDERR "Nothing to print out.\n" and exit 1; ## otherwise print an error
} elsif ($action_clear_ports) {
my $res, my %in_args, my $out_args, my $i=0, my $success=1;
while ($i >= 0) {
%in_args = ('NewPortMappingIndex' => $i);
## search port mapping entry
print STDOUT "Trying to search port mapping entry ...\n" if $verbose;
$res = $service->postaction("GetGenericPortMappingEntry", \%in_args);
## error handling
if ($res->getstatuscode() != 200) {
print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$i = -1; ## stop loop - there are no more entries
} else {
print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
$out_args = $res->getargumentlist();
if ((!$internal_ip) || ($out_args->{'NewInternalClient'} =~ m/^($internal_ip)$/)) {
%in_args = ('NewRemoteHost' => $out_args->{'NewRemoteHost'},
'NewExternalPort' => $out_args->{'NewExternalPort'},
'NewProtocol' => $out_args->{'NewProtocol'});
## remove port mapping entry
printf STDOUT 'Trying to remove port mapping entry number %d...'."\n", $i+1 if $verbose;
$res = $service->postaction("DeletePortMapping", \%in_args);
## error handling
if ($res->getstatuscode() == 714) {
print STDERR "Entry not found. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$success=0;
$i = -1; ## stop loop - there is an error
} elsif ($res->getstatuscode() != 200) {
print STDERR "Operation failed. (ERR ".$res->getstatuscode().")\n\n" if $verbose;
$success=0;
$i = -1; ## stop loop - there is an error
} else {
print STDOUT "Done (OK ".$res->getstatuscode().")\n\n" if $verbose;
}
} else {
$i++;
}
}
}
print STDOUT "Command successful.\n" and exit 0 if $success;
print STDERR "Command failed.\n" and exit 1;
}
sub get_igd_devices() {
my $cp, my @devices, my $device, my @filtereddevs;
$cp = Net::UPnP::ControlPoint->new();
## scan for devices
@devices = $cp->search(st => 'upnp:rootdevice', mx => '1');
## and another time if none found
@devices = $cp->search(st => 'upnp:rootdevice', mx => '3') if (!@devices);
if (@devices) {
foreach $device (@devices) {
my $devtype = $device->getdevicetype();
if ($devtype =~ m/^urn:schemas-upnp-org:device:InternetGatewayDevice:1$/) {
push(@filtereddevs, $device);
}
}
}
@filtereddevs;
}
sub list_devices() {
my @devices, $devcount;
my $devnum, my $devmanuf, my $devmodel, my $devsn, my $devudn, my $devupc;
@devices = $_[0];
$devcount = length(@devices);
for ($devnum = 0; $devnum < $devcount; $devnum++) { $devmanuf = $devices[$devnum]->getmanufacturer();
$devmodel = $devices[$devnum]->getmodelname();
$devsn = $devices[$devnum]->getserialnumber();
$devudn = $devices[$devnum]->getudn();
$devupc = $devices[$devnum]->getupc();
$devsn = "n/a" if (!$devsn);
$devudn = "n/a" if (!$devudn);
$devupc = "n/a" if (!$devupc);
printf STDOUT 'Device: : %d'."\n", $devnum;
printf STDOUT 'Manufacturer : %s'."\n", $devmanuf;
printf STDOUT 'Model : %s'."\n", $devmodel;
printf STDOUT 'Serial number : %s'."\n", $devsn;
printf STDOUT 'UDN : %s'."\n", $devudn;
printf STDOUT 'UPC : %s'."\n\n", $devupc;
}
}
sub readable_size() {
my $size = $_[0];
my $readable;
if ($size >= 1024*1024*1024*1024) {
$readable = sprintf('%.2f TB', $size/1024/1024/1024/1024);
} elsif ($size >= 1024*1024*1024) {
$readable = sprintf('%.2f GB', $size/1024/1024/1024);
} elsif ($size >= 1024*1024) {
$readable = sprintf('%.2f MB', $size/1024/1024);
} elsif ($size >= 1024*1024*1024*1024) {
$readable = sprintf('%.2f KB', $size/1024);
} else {
$readable = sprintf('%.2f Bytes', $size);
}
$readable;
}
__DATA__
igdctl -:- IGD administration tool written in perl
Version 0.1
USAGE
./igdctl.pl [-h|-p|-r|-a|-g|-R|-l|-c|--enable|--disable]
[-d DEVICE] [-E IP] [-e PORT] [-I IP] [-i PORT]
[-P PROTOCOL] [-D DURATION] [-A ACTIVE]
Example:
./igdctl.pl -r
Actions:
-h, --help : Displays this help text.
-v, --verbose : Verbose mode.
-p, --print : Prints connection information avaleble.
--enable : Enable internet access if supported.
--disable : Disable internet access if supported.
-r, --reconnect : Triggers a reconnect.
-a, --add-port : Adds or overwrites a port mapping entry with the
same internal client address.
-e, -I, -i, -P are needed, -E, -D, -A are
optional.
-g, --get-port : Gets a port mapping entry by remote host,
port and protocol. -e, -P are needed, -E is
optional.
-R, --remove-port : Removes a port mapping entry.
-e, -P are needed, -E is optional.
-l, --list-ports : Lists all port mapping entries. If -I was
specified, only entries by a given IP are shown.
-c, --clear-ports : Removes all port mapping entries. If -I was
specified, only entries by a given IP are
removed.
Options:
-d, --device=DEV : specifies the device number when more then one
devices are avaleble.
-E, --external-ip=IP : specifies a remote host. Wildcards are supported.
-e, --external-port=PORT : specifies an external port number.
-I, --internal-ip=IP : specifies a client ip address.
-i, --internal-port=PORT : specifies a client port number.
-P, --protocol=PROTOCOL : specifies a protocol. TCP and UDP are allowed.
-D, --duration=DURATION : specifies a number of seconds until a port mapping
entry expires.
-A, --active=ACTIVE : Specifies whether a port mapping entry is enabled.
Values 0 and 1 are allowed.


Copyright © 2009 Vincent
All Rights Reserved.


Read More......
| 0 comments ]

Introduction



Bash completion is a useful tool for completion of file paths, commands etc. By default it is enabled on Ubuntu but not on Debian. With two simple steps it can also be enabled on Debian.

1. Install bash-completion



First of all we need the install the according package:

apt-get install bash-completion


2. Add it to the bash profile



Either edit the ~/.bash_profile file to enable it only for a given user or edit /etc/profile to add it system-wide. Add the following code:

if [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi

3. Try it



In order for it to work you have to log out and relogin and then you can make use of bash completion the usual way. E.g. issue:

apt-g

and then press the TAB key once and the command will be completed to apt-get. Or issue this:

apt

and then press TAB key twice. You can also try with

apt-get install apa

and then press TAB key once to complete as far as possible and a second time to list all options.




Read More......
| 0 comments ]

This document explains how to set up a fully encrypted para-virtualized XEN instance. In this howto, the host system is running Debian Etch, while the guest system to be installed will be using Debian Lenny.

Introduction

If you are concerned about your privacy, you might want to consider using hard disk encryption to protect your valuable private data from spying eyes. Usually, the easiest way would be to use your distribution's installer to set up a fully encrypted system; I think most recent Linux distributions support this. However, when you are using XEN to provide virtualization, there are situations where you might not want to encrypt your whole computer with all guest instances, but instead only encrypt one OS instance. This howto will deal with exactly this situation. It assumes that the XEN host system is already up and running.

Preparing the XEN instance

Firstly, we need to create the XEN configuration for the new guest instance. This can easily be done with the script xen-create-image from the package xen-tools:

xen:~# aptitude install xen-tools

Now, we need to 'teach' xen-tools the existence of Lenny (since, remember, we're using Etch as the host system):

xen:~# ln -s /usr/lib/xen-tools/debian.d /usr/lib/xen-tools/lenny.d

Now, we can create the XEN instance:

xen:~# xen-create-image --memory 150M --size 1G --noswap --ip 10.0.0.1 --hostname crypto.example.com --dist lenny

This last step installs a very basic Debian Lenny guest system. We will use this system to configure encrypted filesystems and eventually copy its contents over to these encrypted filesystems.

The encrypted filesystem(s) of the new system will all be stored using LVM. So basically, this is kind of a 'LVM inside LVM': We need to create a logical volume on the host system which will be made available to the guest system as /dev/sdX, and inside the encrypted guest system, we will install LVM using this /dev/sdX as physical volume to store our volume group:

xen:~# lvcreate -L24G -n crypto.example.com_crypt vg0

Here we assume that the volume group on the XEN server, which holds the logical volumes of all the XEN instances is called vg0.

By default, xen-create-image creates a configuration file /etc/xen/crypto_unencrypted.cfg. We need to modify this to include the additional logical volume, so that it reads as follows:

kernel  = '/boot/vmlinuz-2.6.18-6-xen-amd64'
ramdisk = '/boot/initrd.img-2.6.18-6-xen-amd64'
memory = '150'
root = '/dev/sda1'
disk = [ 'phy:vg0/crypto.example.com_disk,sda1,w', 'phy:vg0/crypto.example.com_crypt,sda2,w' ]
name = 'crypto.example.com'
vif = [ 'ip=10.0.0.1' ]
on_poweroff = 'destroy'
on_reboot = 'restart'
on_crash = 'restart'

So now we're ready to first start into the newly created system:

xen:~# xm create -c /etc/xen/crypto_unencrypted.cfg

Preparatory steps inside the temporary XEN guest

After logging in, we need to install necessary components:

crypto:~# aptitude install lvm2 cryptsetup

Next, we fill the target partition with random data:

crypto:~# dd if=/dev/urandom of=/dev/sda2

Create the cryptodisk:

crypto:~# cryptsetup -c aes-cbc-essiv:sha256 -y -s256 luksFormat /dev/sda2

Enable LVM to handle cryptsetup devices. For this, add the following to the devices section of /etc/lvm/lvm.conf:

types = [ "device-mapper", 16 ]

Open the crypto device:

crypto:~# cryptsetup luksOpen /dev/sda2 crypt

Create the physical volume and the volume group for LVM:

crypto:~# pvcreate /dev/mapper/crypt
crypto:~# vgcreate vg-crypt /dev/mapper/crypt

Create logical volumes:

crypto:~# lvcreate -L1G -nroot vg-crypt
crypto:~# lvcreate -L2G -ntmp vg-crypt
crypto:~# lvcreate -L12G -nvar vg-crypt
crypto:~# lvcreate -L1G -nswap vg-crypt
crypto:~# lvcreate -L3G -nusr vg-crypt

Now, when creating the logical volumes, there is not exactly 1G of space left on the device but slightly more. We use vgdisplay to find out exactly how much space is left and then create the last volume:

crypto:~# lvcreate -l255 -nusrlocal vg-crypt

And create filesystems:

crypto:~# mkfs.ext3 /dev/vg-crypt/root
crypto:~# mkfs.ext3 /dev/vg-crypt/tmp
crypto:~# mkfs.ext3 /dev/vg-crypt/usr
crypto:~# mkfs.ext3 /dev/vg-crypt/usrlocal
crypto:~# mkfs.ext3 /dev/vg-crypt/var
crypto:~# mkswap /dev/vg-crypt/swap

You might ask yourself why I am creating so many filesystems? Well, this is supposed to become a pretty secure system (after all, otherwise, all the encryption does not help if my system is hacked), so later I will be following the advice of the Securing Debian Handbook (http://www.debian.org/doc/manuals/securing-debian-howto/), which however is not covered in this howto.

Mount the newly created filesystems:

crypto:~# mkdir /mnt/target
crypto:~# mount /dev/vg-crypt/root /mnt/target/

crypto:~# mkdir /mnt/target/usr/local -p
crypto:~# mkdir /mnt/target/var
crypto:~# mkdir /mnt/target/tmp
crypto:~# mount /dev/vg-crypt/usr /mnt/target/usr
crypto:~# mount /dev/vg-crypt/usrlocal /mnt/target/usr/local
crypto:~# mount /dev/vg-crypt/var /mnt/target/var
crypto:~# mount /dev/vg-crypt/tmp /mnt/target/tmp

And copy the currently running filesystem to the encrypted ones:

crypto:~# init s
crypto:~# cp -apx / /target/

Since we copied the data from a running system, we need to clean up a bit:

crypto:~# /bin/rm -fr /target/tmp/*
crypto:~# /bin/rm -fr /target/proc/*
crypto:~# /bin/rm -fr /target/sys/*
crypto:~# /bin/rm /target/etc/mtab

Create the /etc/fstab:

proc                   /proc      proc     rw,nodev,nosuid,noexec 0     0
/dev/vg-crypt/root / ext3 errors=remount-ro 0 1
/dev/vg-crypt/usr /usr ext3 errors=remount-ro 0 1
/dev/vg-crypt/usrlocal /usr/local ext3 errors=remount-ro 0 1
/dev/vg-crypt/var /var ext3 errors=remount-ro 0 1
/dev/vg-crypt/tmp /tmp ext3 errors=remount-ro 0 1
/dev/vg-crypt/swap none swap sw 0 0

As stated above, here you might want to consider the Securing Debian Handbook and apply some additional security tweaks.

For now, stop the guest system:

crypto:~# halt

Back in the XEN Host-System ...

We need to install some necessary tools:

xen:~# aptitude install cryptsetup initramfs-tools

Now we create a XEN configuration file /etc/xen/crypto_encrypted.cfg for the encrypted system:

kernel  = '/boot/vmlinuz-2.6.18-6-xen-amd64'
ramdisk = '/boot/initrd.img-2.6.18-6-xen-amd64_crypt'
memory = '150'
root = '/dev/mapper/vg--crypt-root'
disk = [ 'phy:vg0/crypto.example.com_crypt,sda1,w' ]
name = 'crypto.example.com'
vif = [ 'ip=10.0.0.1' ]
on_poweroff = 'destroy'
on_reboot = 'restart'
on_crash = 'restart'

Now comes the really tricky part about this. We need to create a new initrd image so that the encrypted system actually asks for the disks Key.

First, we create a file /etc/initramfs-tools/conf.d/cryptroot:

CRYPTROOT=target=crypt,source=/dev/sda1,key=none,lvm=vg--crypt-root

Note that even though the volume group which holds the encrypted filesystems is called vg-crypt, we need to 'escape' the '-' with a second dash.

Then, we add the following lines to the file /etc/initramfs-tools/modules:

aes-x86_64
dm-crypt
dm-mod
sha256

Next, we backup our existing initrd image, create a new one and do some renaming:

xen:~# mv /boot/initrd.img-2.6.18-6-xen-amd64 /boot/initrd.img-2.6.18-6-xen-amd64_orig
xen:~# update-initramfs -k 2.6.18-6-xen-amd64 -v -c
xen:~# mv /boot/initrd.img-2.6.18-6-xen-amd64 /boot/initrd.img-2.6.18-6-xen-amd64_crypt
xen:~# mv /boot/initrd.img-2.6.18-6-xen-amd64_orig /boot/initrd.img-2.6.18-6-xen-amd64

So now we are ready to start the encrypted XEN guest:

xen:~# xm create -c /etc/xen/crypto_encrypted.cfg

If all went well, you will be prompted for the Key to the encrypted volume, and the whole systems boots. Enjoy :)

Now you can still clean up a bit:

xen:~# /bin/rm /etc/xen/crypto_unencrypted.cfg
xen:~# lvremove /dev/vg0/crypto.example.com_disk

One important thing: YOU NEED TO BE ABLE TO TRUST THE HOST SYSTEM!!! If the host system is compromised, it might log the console input when you enter the Key for unlocking the cryptsetup device, thus learning the password whith which you encrypted all your data!!!

Sources

While setting up this encrypted XEN guest instance, the following websites proved useful to me:



Read More......
Free Website Hosting

JS-Kit Comments