Squid over SSH

At work we need to externally access some intranet sites that are not visible on the Internet, both for architectural deployment and security concerns.

I manage this with an SSH tunnel and Squid access over it. Security is my first requirement for this kind of remote access, and this configuration will maximize it.

Configuring SSH server on the gateway

First, I work on an SSH externally accessible server that will act as a gateway, configuring the sshd running on it to refuse root login, allowing for TCP port forwarding and gateways. SSHD will listen on a non standard port, to avoid automated attacks from bots:

from /etc/ssh/sshd_config on the gateway:

Port 12345   # use a more strange number for your configuration
PermitRootLogin no
AllowTcpForwarding yes
GatewayPorts yes
X11Forwarding yes

on this gateway, I have only one user account, remoteaccess, with no password. This means that access will be only possible with certificates. After modifications, restart SSH server.

For and on each trustworthy client, I create a certificate on it:

client> ssh-keygen -t dsa

and the resulting public certificate, $HOME/.ssh/id_dsa.pub, has to be added to the authorized keys for the remoteaccess user on the gateway machine:

gateway> cat id_dsa.pub >> /home/remoteaccess/.ssh/authorized_keys

If you are paranoid, you can limit the number of tentative connections made on the gateway machine with some iptables rules. Add to /etc/sysconfig/iptables:

-A INPUT -s WHITELISTNETWORK1 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -s WHITELISTNETWORK2 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --update --seconds 180
         --hitcount 3 --name DEFAULT --rsource -j DROP
-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name DEFAULT
         --rsource -j ACCEPT

if you add these rules, then restart iptables for the new configuration to take effect. The proposed rules will drop an IP when it originates more than 3 connections in 180 seconds. Note that this is made at TCP level, so even successful and legitimate connections are counted. This is why it’s good to white list some IPs (like localhost) or networks (like 10.0.0.0 or whatever).

In my experience, this specific hardening is not required, because it’s sufficient that your SSH server is listening on a non standard port to remove accesses from standard bots, where more sophisticated attack swill be stopped by the SSH certificate-only access. But if you are really paranoid, you can also add portknocking enabled access to your SSH server.

Remember that this gateway must always be updated for critical security fixes. It could be good if it’s running a different operating system than the rest of your infrastructure (e.g. a BSD flavour if you are a Linux shop) because, at the cost of some more management and administration effort, you avoid that the same zero-day security flaw will target all of your systems (this is not necessarily true, because you may end up running the same software on different Unixes, so evaluate pros and cons carefully).

Check that SSH connection is working:

client> ssh -P 12345 remoteaccess@gateway

it works if you have access on the gateway without being asked for a password.

Configuring Squid

Squid will run on the gateway, accepting only proxying requests from clients running on the gateway machine. This could be accomplished in some different ways:

  • configuring squid to accept only requests from 127.0.0.1;
  • definining a iptables rule that stops foreign requests;
  • configuring the external firewall to stop external requests for Squid.

As defense in deep is a good security practice, it’s better if you do all of these: would one of them falling apart, the others will save the day.

The iptables rules:

gateway> iptables -A INPUT -p tcp -m tcp --source 127.0.0.1 --dport 3128 -j ACCEPT
gateway> iptables -A INPUT -p tcp -m tcp --dport 3128 -j DROP

After definition of them, save the new iptables configuration (service iptables save) and restart the service (service iptables restart). As a result, only TCP connections originated from 127.0.0.1 on port 3128 (the standard port of Squid, and there is no need to work on a non default port) are accepted.

Configuration for Squid is made on the (big) /etc/squid/squid.conf file. Critical parameters are:

acl INTRANET dstdomain .intranet.example.com critical.example.com
http_access allow INTRANET
http_access deny all

These three lines defines an acl named INTRANET, that allows for proxying of HTTP request for the critical.example.com server and the *.intranet.example.com domain. These rules must be added (in Squid order of configuration directives is critical) after this point:

# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS

# Example rule allowing access from your local networks. Adapt
# to list your (internal) IP networks from where browsing should
# be allowed
#acl our_networks src 192.168.1.0/24 192.168.2.0/24
#http_access allow our_networks

Note that if you want defense in deep, uncomment the last two lines, defining suitable values for our_networks (our_networks src 127.0.0.1/32)

The configuration above is for RHEL 4.x, which ships Squid 2.4. If you have RHEL 5.x, you have Squid 2.5 that allows for password authentication. In such a case, use these configuration rules:

auth_param digest program /usr/lib/squid/digest_pw_auth /etc/squid/password.txt
auth_param digest realm Example.com Intranet Access
auth_param digest children 2
auth_param digest nonce_max_duration 8 hours
auth_param digest nonce_max_count 1000
acl AUTHUSER proxy_auth REQUIRED
acl INTRANET dstdomain .intranet.example.com critical.example.com

http_access allow INTRANET AUTHUSER

http_access deny all

The file /etc/squid/password.txt will be a simple line:

username:password

Use more lines if you want to discrimate between users. (More authentication schemas are available for Squid). Now (re)start Squid on the gateway.

Client configuration

First, create the SSH tunnel:

client> ssh -l remoteuser -N -T -p 12345  -L 3128:localhost:3128 gateway-hostname-or-public-ip-address

so a connection on the local 3128 port of the localhost will be SSH tunnelled to the port 3128 of the gateway, where Squid is eagerly listening.

Then we need to instruct the client’s browser to proxy request for the intranet domain to port 3128 on localhost, with a Proxy Auto Configuration (PAC) file.

A PAC file example is:

function FindProxyForURL(url, host)
{
  if (shExpMatch(host, "*intranet.example.com"))
    return "PROXY 127.0.0.1:3128";

  if (shExpMatch(host, "critical.example.com"))
    return "PROXY 127.0.0.1:3128";

  return "DIRECT";

}

This file could be put on a web server where it could be accessed for all the clients, or distributed via e-mail, it’s not security sensitive.

After all these steps done, you will access your intranet via SSH, which means you could work even on Sundays.

Posted in rhel. Tags: , , . No Comments »

Red Hat PV drivers made a huge difference

If you, like me, are using Xen with a HVM guest machine (i.e. with an hardware assisted virtualization) you may have experienced horrible network performances for the domU.

I tested the performance with the netperf tool. First result where embarrassing, about 2.5 Mbps. The problem is very common, and it could be someway related to the host NIC. I have run the tests over an HP DL 380 G5, with two Broadcom 5708 on board (it’s the standard configuration for an HP DL server. People have reported that with an Intel chipset based NIC everything works fine).

The problem was that there were a lot of dropped packets and errors, that force TCP entering the congestion avoidance phase, so performances are almost zero.

I’ve unsuccessfully tried to do the following:

All these, combined, give me something, about 50 Mbps, but there are still dropped packets and transmission errors.

On the RHEL 5 mailing list, someone reported that are now available the para-virtualized drivers for RHEL 5. I’ve tried them, following the Red Hat guide, and performances jumped to an incredible 345 MBps of sustained throughput (for two domU on the same dom0: i.e. they are memory-to-memory transfers).

(funny enough, now I’ve found an italian guide describing the same problem, although it seems to me they’re wrong in identifying the root cause: it’s not the virtual NIC speed the problem, the errors are).

Pinnacle 50i with Fedora 8 64bit

Problem statement: I have a Pinnacle 50i and I want it working on Fedora 8 64 bit.

Symptoms:

  • The card works well with Windows XP, I have audio and video, so if audio is missing on Linux it’s not a cable problem;
  • On Linux, I got the video but not the audio. On Fedora 6, the audio was present but feeble, which suggests that the problem is part due to kernel module configuration and part to Pulseaudio.

Solution steps:

  • On /etc/modprobe.conf, tell the system that we want to use a saa7134 card plus the module to get its audio output feed into the ALSA subsystem:

options saa7134 card=77 video_nr=1 vbi_nr=1 radio_nr=1
install saa7134 /sbin/modprobe –ignore-install saa7134; /sbin/modprobe saa7134-alsa

  • As root issue: modprobe saa7134-alsa. Check that you have the card as an audio source:

$ arecord -l

**** List of CAPTURE Hardware Devices ****
card 0: CK8S [NVidia CK8S], device 0: Intel ICH [NVidia CK8S]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: CK8S [NVidia CK8S], device 1: Intel ICH - MIC ADC [NVidia CK8S - MIC ADC]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 2: SAA7134 [SAA7134], device 0: SAA7134 PCM [SAA7134 PCM]
Subdevices: 0/1
Subdevice #0: subdevice #0

  • You have to make some kind of magic sound rerouting, instructing sox to connect the output of the card to the input of the ALSA subsystem:

$ ls -l /dev/dsp*

crw-rw—-+ 1 root root 14, 3 2008-01-27 12:50 /dev/dsp
crw-rw—-+ 1 root root 14, 35 2008-01-27 13:31 /dev/dsp2
$ sox -c 2 -s -w -r 32000 -t ossdsp /dev/dsp2 -t ossdsp -w -r 32000 /dev/dsp

  • Now you can start your tv viewer of choice (yum install tvtime kdetv to have them both). It’s possible that tvtime search for a /dev/video0 device whilst you have /dev/video1. If this happens, issue tvtime-configure -d /dev/video1 to fix for the configuration file.
  • Enjoy watching tv, which is something impossible on Sunday afternoon in Italy due to the very poor quality of what’s aired.

Some interesting links:

Read the rest of this entry »

Multiple Rails applications proxyed by Apache 2.0

At the $JOB we are moving from a traditional LAMP stack to a Ruby on Rails based one. Security has always been central, so we choose to have one operating system user for each application: if an application experiences a security flaw, it could not affect the others as the operating system will prevent from accessing and manipulating files and data that belong to other users. Of course, an application flaw plus a kernel privilege escalation could be a bit more problematic, but it’s a lot more unlikely that two different security problems appear at the same time, so you can keep your kernel (and core libraries) updated and you should be able to contain the problem.
Beside this, we want to have only one access point for the Rails applications, a kinda of grown up intranet-extranet portal where each application is developed by an agile methodology (at least, the developers told me so) so they could more easily updated: it’s like a specific task for a specific application task.
If you search the Internet, you’ll find a lot of example to configure Apache 2.2 to work with Mongrel, leveraging on mod_proxy_balancer. But Red Hat 4.x ships with Apache 2.0, so we need to went another way.
(Note: some of the next is based on some other blogs I’ve read. I’m stupid enough to be unable to remember them, but if you feel it could be your blog and work I’m standing on, tell me and I’ll credit).
The scenario we consider is this one:
  • we have an example.com access site, that could or could not has some contents of its own;
  • we have a first Rail application, called First App, that should be accessed with the starting URL http://example.com/firstapp;
  • we have a second Rail application, called Second App, that should be accessed with the starting URL http://example.com/secondapp;
  • (we need someone payed to find fancy names for our applications, by the way);
Configuration of First App and Second App from the Mongrel point of view is somewhat made, as an example by using my Mongrel helper script. One way or the other, we have that First App is listening on ports 3000,3001,3002, and Second App on 3003 and 3004.
So we first write a file that will tell Apache where each application is listening:
$ cat firstapp.ports
ports 3000|3001|3002
$ cat secondapp.ports
ports 3003|3004
then we define the VirtualHost section for example.com (if you don’t have a virtual host based setup, skip the <VirtualHost> and </VirtualHost> markups):
<VirtualHost *:80>
ServerName example.com
ProxyRequests Off
# First app
ProxyPassReverse /firstapp http://127.0.0.1:3000/
ProxyPassReverse /firstapp http://127.0.0.1:3001/
ProxyPassReverse /firstapp http://127.0.0.1:3002/

# Second App
ProxyPassReverse /secondapp http://127.0.0.1:3003/
ProxyPassReverse /secondapp http://127.0.0.1:3004/

ProxyPreserveHost On
RewriteEngine On

# Rewriting maps
RewriteMap mongrelfirstapp   rnd:/path-to/firstapp.ports
RewriteMap mongrelsegreteria      rnd:/path-to/secondapp.ports

# Rewrite for example.com/firstapp
RewriteCond %{REQUEST_URI} ^/firstapp.*
RewriteRule ^/(.*) http://localhost:${mongrelfirstapp:ports}/$1 [P,L]

# Rewrite for example.com/secondapp
RewriteCond %{REQUEST_URI} ^/secondapp.*
RewriteRule ^/(.*) http://localhost:${mongrelsecondapp:ports}/$1 [P,L]

#RewriteLogLevel 9
#RewriteLog logs/rewrite-example.com.log
ErrorLog logs/error-example.com.log

The ProxyPassReverse directives instruct Apache on how to deal with the Mongrel back-end servers, you need one directive for every listening Mongrel. Then, we define two RewriteMap, one for each application, called mongrelfirstap and mongrelsecondapp. These rewriting maps choose a random value for the port parameter, due to the rnd: prefix. Then we tell Apache that: if the URI starts with /firstapp, it should proxy [P] the request to one of the three Mongrel serving the first application, choosing it randomly (mongrelfirstapp:ports), and this must be the last URL rewriting rule to apply for this request [L]. Otherwise, if the URL is starting with /secondapp, it should do the same with respect che Mongrel servers serving Second App. Otherwise, it will serve the URI with the standard Apache mechanism. If example.com is itself served via mongrel, you can add other configuration directives where the prefix is not /firstapp but a simple /.

Speaking about prefix, the Mongrel istances must be started with the –prefix parameter that should equal the part defined in the RewriteCond (so, –prefix=/firstapp and no trailing slash). It’s possible to made some syntactic sugar to avoid this, but I prefer that the application itself has an idea on where is located.

About performance: this configuration will proxy every request, included the ones asking for static content. It’s possible to define some rewrite conditions that result in the intervention of Mongrel instances only when there’s actually some Rails code to parse, otherwise relying on Apache, but I don’t need this in my setup.

Why Sun acquired MySQL AB

ACM Queue, Vol. 5. No. 6 Sep/Oct 2007, “A Conversation with Jeff Bonwick and Bill Moore“:

“If you have a database sitting on top of a transactional file system, the database is sitting up there being very careful about ordering its writes to the log and being clear about saying when it wants to know this stuff is flushed out. Then beneath it, you’ve got this transactional file system creating transaction groups, putting in a bunch of changes, and then committing those out to disk atomically.
Why not have a blending of the layers where basically the whole back end o the database - the part that isn’t parsing the SQL - participates directly in the transaction groups that ZFS provides, so that consistency is no longer a problem the database has to solve? It can be handled entirely by the storage software below”.
So, Sun has acquired MySQL AB to spreads the adoption of its ZFS file system. Interestingly enough, MySQL has a plugin based architecture, so it’s possible do define more than one data-engine to deal with your data. Saying that we’ll soon see a plugin for MySQL that leverages on ZFS it’s even too easy.
Now that this acquisition is done, I could write some more. About one year ago I heard rumors that Red Hat was considering to buy MySQL AB, and that they stopped at the very last time as they prefer not to put their relationship with Oracle at risk. It’s entirely possibile (but it’s a my own speculation) that Oracle Enterprise Linux came out as a stop signal for Red Hat, which got the message.
Now, some key pieces of a modern Linux installation (Java stack, MySQL database) that Red Hat supports and offers to its customer, are owned by Sun, which became a key player in the Linux market. Another speculation is that, in a one-two years time, Solaris will be the best choice for a “LAMP” architecture, to rename it “SAMP”.
Yes, you can use Ruby on Rails if you want to depart from PHP and avoid Java, but recall to your mind who is behind JRuby, and you got the picture.
Posted in mysql, oss. Tags: , , . No Comments »

Review: Essential SNMP, 2nd edition

Last previous entry in this blog was one month ago, I’m unhappy with this but as I need to write down my Ph.D. dissertation by two or three months’ time I’m feeling the pressure and have very little time. But the life continues and goes on, so I’m still a Linux system administrator, and as such I feel that the most important skill I must develop is in the monitoring area. Only if you have a monitoring system that helps you track down software and, more important, hardware failures, you can successfully administer a large cluster of machines and being productive and pro-active, otherwise you’ll simply waste your time by fixing the today’s problem, and tomorrow will be another day with a tomorrow’s problem.
This may sound very common if you work in a corporate environment, but in Italy we have very few big customers, so the idea of monitoring is very well confined in some magic gardens where you are usually not invited. To learn the path for these gardens, I decided that this year I should focus on enterprise monitoring, and I started with the very basic of it, the SNMP protocol.
If you dig on the Internet for SNMP, you find some interesting tutorials, I greedily read them but I realized that I need something more robust and comprehensive. For my forma mentis (a latin expression that means shape/settings/idea of your mind, plus with no Wikipedia entry) I cannot successfully use a layer 7 tool if I don’t have a good idea of the communication protocol it will rely on. So I searched for an in-depth book and I finally landed on Essential SNMP, second edition from O’Really.
I found it’s an excellent book to understand what SNMP is and how it works, from the definition to packet sniffing on the network to see real data exchange. Also there are some real programming example if you want to write your own SNMP agent, so it’s a good starting point when you need to interact with an heavy customized environment.
But it’s a bit outdated, as every example in the book is about configuring and using HP OpenView, whilst open source tools like Nagios , Zabbix, Zenoss and OpenNMS have no more than some pages (if any) in the appendixes.
These tools, for what I’ve understand now, are usually hybrid, meaning that they covers both the hardware level monitoring function and the software one. Some of them, like Nagios, comes from application level monitoring and have some SNMP extensions, others are natively in the application layer and go deep in the stack, others were designed with the idea to cover both areas. They are very different in installation requirements, required configuration efforts, ease of maintenance. Some of them have a lot of plugins that makes the interaction with the hardware or the applications easy, some requires more tweaking. Even support is completely different, ranging from a free consultancy market to a single company that writes the software, give it to you for free, and try to made revenues from the support service.
So, to go back to the long term project, I think that I should understand how these oss solutions work, compare them, and deploy one or more of them to have a complete control over the infrastructure.

NYSE will move to Linux

NY Times reports that the New York Stock Exchange is heavily investing in Linux. Tech speaking:

  • they prefer Linux over IBM-AIX and HP-UX, and they have HP hardware (Opteron blades and Integrity);

  • they will use HP OpenView for monitoring;

  • they are already using Solaris on some systems, but prefer to move to a more open system;

  • they do not like virtualization, as it introduces not negligible latency.

Using Linux (in the Red Hat or SuSE flavor, I guess. Note that Red Hat is listed on NYSE) will be of big impact to financial institutions world-wide, as the volume of data and money processed by the NYSE is simply enormous: NYSE is saying that Linux is mature enough although is not so polyshed as other Unix dialects. Some feature are missing (as an example, backup of an entire system, a la mksysb in IBM AIX) but these things can usually be managed at the infrastructure level: if you system is completely redundant, you can put offline small portions of it and do the planned maintenance tasks. It will cost money for the redundancy (which is possible you would pay in every case) but it’s entirely possibile that it would be cheaper than paying the high licenses for other unixes, especially when, in the long term you will found yourself vendor locked-in.

Latency in virtualization is a big problem, best known as os interference (see this good article from IBM) that will severely impact performances for HPC clusters and could be desruptive for financial trading systems, where you receive hundreds of different data feeds per second, and you should decide what to buy or sell according to some heuristics before your competitors. It will be interesting to see what the Red Hat MRG platform will do in this field. As usual, we are at the beginning of the open source world.

Mongrel integration for RHEL, Fedora and derivatives: new release

I have made a new release of my script for controlling mongrel instances in RHEL, Fedora and derivatives.

The most important thing is that now you can selectively choose which instances start or stop. To do so, after the start or stop directive, you can add a prefix, each filename starting with that prefix (and ending with .conf, as usual) will be processed.

As an example, if you have these instance description files in your /etc/mongrel:

testsite.internal.example.com.conf
newapp.internal.example.com.conf
newportal.internal.example.com.conf
fileserver.extranet.example.com.conf

a command line as service mongrel start test will start each instance described by a filename like test*conf, so for the above example you’ll start the instance(s) described in testsite.internal.example.com.conf. In the same way:

  • service mongrel start new will start instances described in newapp.internal.example.com.conf and newportal.internal.example.com.conf;

  • service mongrel stop newapp will stop instance(s) described in newapp.interna.example.com.conf (newportal.etc won’t be touched);

If you don’t specify any prefix, the command will be applied on all files. Note that service mongrel status will ignore any prefix.

Click on the link to download the mongrel service script.

Upgrading from Fedora 6 to Fedora 8 via yum

I’ve successfully perfomed an update from Fedora 6 64bit to Fedora 8 64 bit, this won’t be a news except that, to make things more spicy, I choose to perform this update by yum.

I read that Anaconda has some troubles in updating from previous releases to Fedora 8 (it hangs with packages fromdifferent repositories) and, more important, I am too lazy to download a whole DVD and prefer doing things the fancy way, so I decided to go along the yum way.

First, I installed the Fedora Release RPM (see here), then I eagerly launched yum to see if it’s capable of deploying such a massive upgrade (yes, I’m doing this in the spirit of testing). Yum found that 1350+ packages must be downloaded, for a grand total of 1.4 GB of new software. After download, it started the upgrade process, made of 2700+ steps.

This wasn’t without some harshness, because yum need some help from me: I manually remove some packages, they conflict with packages from Fedora 8 that yum was pulling in. In this ward there are mostly packages from third party repositories that I installed once and the forgot to have.

Unfortunately, yum stuck at step 1950 circa, I guess because I submitted from another console a simple rpm -qa statement: it’s sad to say, but still today we - inhabitants of the RPM world - are experiencing deadlocks. So I choose to remove all the packages from Fedora 6, and I define this sets as “all the packages with “.fc6″ in their name”. By this definition, I remove keyutils-libs, and as a result after the boot SSH server, X Server, yum failed to start.

Yum reports a cryptic message, complaining about a SHA256 missing module, good for me that SSH server startup fails with a more informative string. I installed the package, fixed the entry in /etc/fstab (no more /dev/hd<n> for us! Labels everywhere) and now I’m posting about it.

(Thinking about it, I devised that the best way to find no longer used packages is the package-cleanup –orphans command)

First impressions: Firefox (which is now the 64 bit application shipped with Fedora, not the 32 bit application downloaded the site I used to have) is really faster, and I have the distinctive feeling that the whole desktop is more responsive. Getting help for a 64 bit installation (which is somewhat less mainstream) is as easy as googling for it and going to Fedora 64 web site.

Two years ago the landscape was completely different, but Red Hat is no longer the leader in the desktop market, Ubuntu holds the sceptre. A problem for Red Hat, because the boys that today are using Linux on their desktop are the men that tomorrow will use Linux on their server (think of Microsoft). They need to regain popularity, and it seems to me that they are headed in the right way.

Posted in fedora. Tags: . No Comments »

How to manipulate the files stored inside a Xen virtual machine

Assume you have created a Xen virtual machine, and its data are stored on a file. You might want to access the files stored inside the machine (even when the machine is not running) for one reason or another:

  • inspect them;
  • change some of them, as an example you copy the virtual machine imagine file to another physical host and you need to change some settings (e.g. network-related) in order to fit the virtual machine for the new host;
  • doing some post-mortem analysis and/or recovery;

If you search on the net, you may find this document from IBM that will give you some hints, assuming that on the virtual machine you don’t use LVM. I will move a step further, with the the procedure for dealing with virtual machine image file containing a LVM partition.

For the rest of the discussion, I assume you know what a loop backed file system is and how LVM works. Instead of saying “virtual machine file”, i.e. a file on the host that is the disk of the virtual machine, I would say “virtual disk”.

 

1. Be sure the virtual machine it’s shutted down

This is required to avoid metadata corruption.

 

2. Use losetup to associate the virtual disk to a block device

$ losetup -d /dev/loop0 virtual-disk

3. Use fdisk to get information about the block device

$ fdisk -l -u /dev/loop0

Disk /dev/loop0: 8388 MB, 8388608000 bytes
255 heads, 63 sectors/track, 1019 cylinders, total 16384000 sectors
Units = sectors of 1 * 512 = 512 bytes

      Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1   *          63      208844      104391   83  Linux
/dev/loop0p2          208845    16370234     8080695   8e  Linux LVM

This shows that the virtual machine has a tiny initial partition (probably the /boot) and a LVM partition.

4. Use losetup, again, to associate a specific partition of the virtual disk to a specific block device.

If you want the /boot partition:

$ losetup -o $((512*63)) /dev/loop1 /dev/loop0

$ mount /dev/loop1 /mnt

the magic here is the -o parameter, which defines the offset from the beginning of /dev/loop0: 63 sectors, as seen above from the fdisk output. If you want the files in the LVM partition, see next point.

5. Accessing LVM inside a loop device.

$ mount -o $$(208845*512) /dev/loop2 /dev/loop0

To scan the volume groups and the logical volumes, you need to tell to LVM that the /dev/loop<n> devices may contain LVM data. So, edit /etc/lvm/lvm.conf, find the line that defines the “types” parameter:

# types = [ "fd", 16]

it’s a comment, showing the default value. Immediately after, put this line:
types = [ "fd", 16, "loop", 1]

and see what happens:

$ vgscan

  ACTIVE            '/dev/system/root' [14.62 GB] inherit
  ACTIVE            ‘/dev/system/home’ [97.66 GB] inherit
  ACTIVE            ‘/dev/system/tmp’ [512.00 MB] inherit
  ACTIVE            ‘/dev/system/swap’ [4.00 GB] inherit
  inactive          ‘/dev/VolGroup00/LogVol00′ [5.75 GB] inherit
  inactive          ‘/dev/VolGroup00/LogVol01′ [1.94 GB] inherit

So we eventually can access the LogVol00 which contains data (someone tells me that LogVol01 is a swap partition):

$ vgchange -a y

 4 logical volume(s) in volume group "system" now active
 2 logical volume(s) in volume group "VolGroup00" now active

$ mount /dev/VolGroup00/LogVol01 /mnt/

Now the files of the virtual machine are accessible from the /mnt mount point.

6. Unmount all

$ umount /mnt
$ vgchange –activate n VolGroup00
$ losetup -d /dev/loop2
$ losetup -d /dev/loop1
$ losetup -d /dev/loop0

Remove the type parameter from /etc/lvm/lvm.conf if you feel you won’t need it anymore (if it’s present it does not hurt, though).

7. Some notes

  • Remember that the LVM namespace is unique across the system, so your virtual machine must use volume group name and logical volume name different from the ones of the physical host;
  • If you need to change the UUID of the virtual disk, see the uuidgen.py from the Xen distribution for some hints.
  • A different approach, based on kpartx, is available in the Fedora Wiki.