Mounting flash sticks or memory cards on Debian

Usually modern desktop Linux distributions make it easy to automatically mount external storage media like USB flash sticks. But if all else fails this article may help you.

Kernel

Compile a kernel with SCSI disk support (CONFIG_BLK_DEV_SD), multiple LUN support (CONFIG_SCSI_MULTI_LUN – otherwise the x-in-1 card reader will not work) and USB storage support (CONFIG_USB_STORAGE).

Plug it in

Plug the device/flash card in and watch your syslog. It should show something like:

May 12 19:09:57 aldi kernel: usb 2-1: new full speed USB device using address 5
May 12 19:09:57 aldi kernel: scsi5 : SCSI emulation for USB Mass Storage devices
May 12 19:09:57 aldi kernel:   Vendor: MATSHITA  Model: DMC-FZ20          Rev: 0100
May 12 19:09:57 aldi kernel:   Type:   Direct-Access                      ANSI SCSI revision: 02
May 12 19:09:57 aldi kernel: SCSI device sde: 246017 512-byte hdwr sectors (126MB)
May 12 19:09:57 aldi kernel: sde: assuming Write Enabled
May 12 19:09:57 aldi kernel: sde: assuming drive cache: write through
May 12 19:09:57 aldi kernel:  sde: sde1
May 12 19:09:57 aldi kernel: Attached scsi removable disk sde at scsi5, channel0, id 0, lun 0
May 12 19:09:57 aldi kernel: Attached scsi generic sg4 at scsi5, channel 0, id 0, lun 0,  type 0
May 12 19:09:57 aldi kernel: USB Mass Storage device found at 5
May 12 19:09:57 aldi udev[6641]: creating device node '/dev/sg4'
May 12 19:09:57 aldi udev[6624]: configured rule in '/etc/udev/rules.d/z_hal-plugdev.rules[2]' applied, 'sde' becomes '%k'
May 12 19:09:57 aldi udev[6624]: creating device node '/dev/sde'
May 12 19:09:57 aldi udev[6658]: configured rule in '/etc/udev/rules.d/z_hal-plugdev.rules[2]' applied, 'sde1' becomes '%k'
May 12 19:09:57 aldi udev[6658]: creating device node '/dev/sde1'
May 12 19:09:57 aldi scsi.agent[6666]:      sd_mod: can't be loaded (for disk)

You can see what kind of device was detected and that udev has created device nodes /dev/sg4, /dev/sd3 and /dev/sde1 which you could mount. Or better: let the system tell you the partition schemes on the devices:

$> fdisk -l /dev/sde1

Disk /dev/lumix: 125 MB, 125960704 bytes
8 heads, 32 sectors/track, 961 cylinders
Units = cylinders of 256 * 512 = 131072 bytes

     Device Boot      Start         End      Blocks   Id  System
/dev/sde1                 1         961      122959+   6  FAT16

Fixed mountpoint

It’s not very nifty to guess which device the card it mounted on. So you can use udev to assign it a fixed device name.

Try a:

udevinfo -a -p /sys/block/sde

At least one device will probably spit out something like this:

device '/sys/block/sde' has major:minor 8:64
  looking at class device '/sys/block/sde':
    SUBSYSTEM="block"
    SYSFS{dev}="8:64"
    SYSFS{range}="16"
    SYSFS{removable}="1"
    SYSFS{size}="246017"
    SYSFS{stat}="      12      348      360      286        0        0        0       0        0      286      286"

follow the class device's "device"
  looking at the device chain at '/sys/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/host5/5:0:0:0':
    BUS="scsi"
    ID="5:0:0:0"
    DRIVER="sd"
    SYSFS{detach_state}="0"
    SYSFS{device_blocked}="0"
    SYSFS{max_sectors}="240"
    SYSFS{model}="DMC-FZ20        "
    SYSFS{queue_depth}="1"
    SYSFS{rev}="0100"
    SYSFS{scsi_level}="3"
    SYSFS{state}="running"
    SYSFS{timeout}="30"
    SYSFS{type}="0"
    SYSFS{vendor}="MATSHITA"

  looking at the device chain at '/sys/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/host5':
    BUS=""
    ID="host5"
    DRIVER="unknown"
    SYSFS{detach_state}="0"

  looking at the device chain at '/sys/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0':
    BUS="usb"
    ID="2-1:1.0"
    DRIVER="usb-storage"
    SYSFS{bAlternateSetting}=" 0"
    SYSFS{bInterfaceClass}="08"
    SYSFS{bInterfaceNumber}="00"
    SYSFS{bInterfaceProtocol}="50"
    SYSFS{bInterfaceSubClass}="06"
    SYSFS{bNumEndpoints}="02"
    SYSFS{detach_state}="0"
    SYSFS{iInterface}="00"

  looking at the device chain at '/sys/devices/pci0000:00/0000:00:1d.1/usb2/2-1':
    BUS="usb"
    ID="2-1"
    DRIVER="usb"
    SYSFS{bConfigurationValue}="1"
    SYSFS{bDeviceClass}="00"
    SYSFS{bDeviceProtocol}="00"
    SYSFS{bDeviceSubClass}="00"
    SYSFS{bMaxPower}="  2mA"
    SYSFS{bNumConfigurations}="1"
    SYSFS{bNumInterfaces}=" 1"
    SYSFS{bcdDevice}="0010"
    SYSFS{bmAttributes}="c0"
    SYSFS{detach_state}="0"
    SYSFS{devnum}="5"
    SYSFS{idProduct}="2372"
    SYSFS{idVendor}="04da"
    SYSFS{manufacturer}="Panasonic"
    SYSFS{maxchild}="0"
    SYSFS{product}="DMC-FZ20"
    SYSFS{speed}="12"
    SYSFS{version}=" 1.10"

  looking at the device chain at '/sys/devices/pci0000:00/0000:00:1d.1/usb2':
    BUS="usb"
    ID="usb2"
    DRIVER="usb"
    SYSFS{bConfigurationValue}="1"
    SYSFS{bDeviceClass}="09"
    SYSFS{bDeviceProtocol}="00"
    SYSFS{bDeviceSubClass}="00"
    SYSFS{bMaxPower}="  0mA"
    SYSFS{bNumConfigurations}="1"
    SYSFS{bNumInterfaces}=" 1"
    SYSFS{bcdDevice}="0206"
    SYSFS{bmAttributes}="c0"
    SYSFS{detach_state}="0"
    SYSFS{devnum}="1"
    SYSFS{idProduct}="0000"
    SYSFS{idVendor}="0000"
    SYSFS{manufacturer}="Linux 2.6.9 uhci_hcd"
    SYSFS{maxchild}="2"
    SYSFS{product}="Intel Corp. 82801EB/ER (ICH5/ICH5R) USB UHCI #2"
    SYSFS{serial}="0000:00:1d.1"
    SYSFS{speed}="12"
    SYSFS{version}=" 1.10"

  looking at the device chain at '/sys/devices/pci0000:00/0000:00:1d.1':
    BUS="pci"
    ID="0000:00:1d.1"
    DRIVER="uhci_hcd"
    SYSFS{class}="0x0c0300"
    SYSFS{detach_state}="0"
    SYSFS{device}="0x24d4"
    SYSFS{irq}="19"
    SYSFS{subsystem_device}="0x80a6"
    SYSFS{subsystem_vendor}="0x1043"
    SYSFS{vendor}="0x8086"

  looking at the device chain at '/sys/devices/pci0000:00':
    BUS=""
    ID="pci0000:00"
    DRIVER="unknown"
    SYSFS{detach_state}="0"

Look for entries like BUS="scsi" here. The line SYSFS{model}="DMC-FZ20        " seems to point to our USB device in question. So you need to go to /etc/udev/rules.d and create a file (which has a ".rules" suffix) there which reads:

BUS=="scsi", SYSFS{model}=="DMC-FZ20*", KERNEL=="sd?1", NAME="%k", SYMLINK="lumix"

Since the files in the rules.d directory are scanned in order of the file names you may want to call the file something like 010_my.rules

This will make udev look for new devices on the SCSI bus (USB flash devices are handled like SCSI devices), check if the model name starts with "DMC_FZ20" (there are often trailing spaces – thus the ‘*’) and has it create a symlink to /dev/lumix so we don’t have to guess which /dev/sd? device it has become. Don’t forget to restart udev.

Mounting

Create a mount point for your device (mkdir /mnt/lumix) and be sure to create an entry in your /etc/fstab so it’s easy to mount:

/dev/lumix      /mnt/lumix      vfat    user,noauto             0       0

Try a mount /mnt/lumix and you should find your data on /mnt/lumix afterwards.

Now if you use KDE it’s easy to create an icon for a partition called /dev/lumix and you can easily mount and unmount the device. Always unmount the card first or the cache will not be written to the flash card which will likely lead to data corruption on the card. You have been warned.

See also

Since you are hopefully using Debian you will find a more complete documentation on writing rules files in /usr/share/doc/udev/writing_udev_rules/index.html

Bareos/Bacula Cheat Sheet

Bacula is a nifty backup software that is network-capable and stores data in the database for faster retrieval in case you need a certain file back. As a big fan of cheat sheets I created this cheat sheet.

What’s up?

Which files shall be backed up?show filesetsI=Included, E=Excluded
What’s the server doing?status dir
What’s the status of a certain job?status jobid=xx
What’s the client doing?status client
What’s the streamer doing?status storage
Anything new?messages

Backing up

Start a backuprun…and choose the backup job
Label a new tapelabel…and run mount afterwards

Restoring

The common way (a user accidentally removed a file and wants the newest version back from the tapes:

  • Use the restore command.
  • Choose option 5 (Select the most recent backup for a client).
  • cd / ls / dir / mark / markdir / unmark / unmarkdir / lsmark / estimate / pwd / count / find
  • done

Jobs

Last jobslist jobs…or list jobid=xx’ for a specific job
Statistics about last jobslist jobtotal
Which files were backed up?list files jobid=xx

Job status

Statusmeans…
TTerminated normally
CCreated but not yet running
RRunning
BBlocked
ETerminated in Error
eNon-fatal error
fFatal error
DVerify Differences
ACanceled by the user
FWaiting on the File daemon
SWaiting on the Storage daemon
mWaiting for a new Volume to be mounted
MWaiting for a Mount
sWaiting for Storage resource
jWaiting for Job resource
cWaiting for Client resource
dWating for Maximum jobs
tWaiting for Start Time
pWaiting for higher priority job to finish
WTerminated with warnings

Tapes

Which tapes are in the pool?list media
Remove a tapedelete media
Which pools are defined?list pools
Which tapes are/were used for a certain job?list jobmedia
Assign a tape to a certain pooladd
Change parameters of a tapeupdate volume

Troubleshooting

Erase a label on the tapemt rewind && mt weof && mt rewind

Terminology

Catalog

It is data in a SQL database running on the Bareos server. The catalog stores information about all assets like jobs, clients and media. Without the catalog Bareos had no idea which files were backed up and cannot restore them. In case of a disastrous loss of the catalog you need to take the latest bootstrap and start restoring the catalog first using that information. So the catalog itself is also backed up because without it the system is useless.

Volumes

Volumes (also called “media”) are either files on disk or physical tapes. When backups run they save their data to volumes. Bareos keeps track in the catalog which data can be found on each volume. Usually multiple backups run in parallel leading to a multiplexed stream of data written to volumes. A volume always belongs to exactly one pool. Volumes have names/labels – tapes have the name that is printed on the barcode sticker if the library have a barcode scanner.

Pool

A set of volumes. The pool can define a maximum number of volumes, the type of volumes (e.g. disk or tape) and the retention period. For example you can have short-lived disk pools for small frequent backups. On the other hand you may have long-lived tape pools that store data for several weeks or months.

Job

A specific action like a backup, restore or copy (e.g. from disk to tape). Jobs are usually started automatically by the director following a pre-defined schedule. Multiple jobs can run in parallel and share their resources. The catalog keeps track of which jobs have run in the past in order to know which volumes would be required to restore data from them.

In the bconsole you can see the running, past and scheduled jobs by running “stat dir”.

Job definition (aka jobdef)

The definition of a job. It is not stored in the catalog but in text files in /etc/bareos.

Client

A server to be backed up. Usually a file-daemon runs on the client. The director will talk to the client to run jobs.

Fileset

Defines which files or directories to backup from a certain server. A job defines which fileset to use for a backup.

Bootstrap

A small text file usually sent out via email frequently. It is required in case of a catalog loss to find the volume that contains the last backup of the catalog.

The upstream documents reads: “The bootstrap file contains ASCII information that permits precise specification of what files should be restored, what volume they are on, and where they are on the volume. It is a relatively compact form of specifying the information, is human readable, and can be edited with any text editor.”

The bootstrap data is not confidential and should be forwarded to an external location in case of a disaster.

Message

Bareos can send messages to the console or via email. Results of jobs are sent via email.

Schedule

A definition of how often and at what time a job can be run.

Storage

Defines a way to write volumes. It is used by the storage daemon. A storage can be a path on the local disks or the name of the tape device. Autochangers (aka “tape libraries”) are also supported.


Retention

A volume is locked after being written to. The retention period defines when the volume can be overwritten again.

Scratch

This applies to tape volumes only. New tapes can be introduced into the “Scratch” pool. If a pool is out of volumes to use then Bareos will take a volume from the Scratch pool and take it into its own pool.

Levels

Backups can happen in three different levels: Full, Differential and Incremental. Only Full backups are required. The other levels can be used to save space on volumes.

  • Full: every single file defined in assigned fileset is saved to the volume
  • Differential: only new files that were not contained in the last Full backup are backed up
  • Incremental: only new files that were not contained in the last Differential or Incremental backup are backed up

Using only Full backups is secure because if you lose a full backup then you take the full backup before it. However you are stubbornly backing up the same files time and again thus wasting space on the volumes. Complete restores are fastest though because only the last full backup has to be considered.

Using Full and Differential backups saves some space. During restores the last Full and last Differential backup are considered. However multiple Differential backups may store files redundantly thus wasting a little space.

Using Full and Incremental backups saves most space. However for a restore all Incremental backups since the last Full backup need to be working. If one Incremental backup is broken in the chain then only the last Full backup can be restored.

Using Full + Differential + Incremental backups saves most space while still keeping the risk of losing data low. A restore requires the Incremental backups back up to the last Differential backup + the last Full backup. This could look like:

  • Full
    • Differential
      • Incremental
      • Incremental
      • Incremental
      • Incremental
    • Differential
      • Incremental
      • Incremental
      • Incremental <–
      • Incremental
  • Full

To restore the highlighted Incremental backup you would need the previous Differential and Full backups printed in bold letters.

Which mode to use depends on the type of data to backup. Database directories usually change in its entirety so a Full backup is the best solution. File servers with millions of files gain some advantage from using Full, Differential and Incremental backups.

Dangerous configurations:

  • Using a rare Full backup and rely on many intermediate Incremental backups. If any of the many Incremental backups were faulty you would lose all data back to that time.
  • Losing the Full backup and only keeping Incremental backups. This may occur if the retention periods are not adequately configured for Full backups.

Co-maintaining a Debian package with Git and git-buildpackage

Although I’m still not entirely comfortable with Git for revision control I partly use it to maintain my Debian packages. Mainly because hg-buildpackage has been abandoned and git-buildpackage is actively maintained. This article deals with co-maintaining a Debian package with Git and git-buildpackage.

Install Git

On the development workstation (where you build the packages – running Sid):

  • aptitude install git-core git-buildpackage pristine-tar

Make sure you set your name and email address in your ~/.gitconfig file via:

  • git config –global user.name ‘<name>’
  • git config –global user.email ‘<email>’

On the publicly available web server (where you publish your repository – Lenny or newer):

  • aptitude install git-core git-daemon-run gitweb 

Move an existing Debian source package under Git control (only if there is not yet a repository containing the package!)

Either: Import the source package into a fresh Git repository

  • git-import-dsc –pristine-tar /path/to/package*.dsc

This creates a package/ directory containing a Git repository with two branches. The default branch “master” contains the debianized source package (like what you would get after running ‘dpkg-source -x *dsc’). The other “upstream” branch contains what was in the orig.tar.gz upstream tarball. You can see the branches with ‘git branch -a’. Each upstream version gets a tag like “upstream/1.3.4” and each Debian package gets a tag like “debian/1.3.4-3”. You can see the tags with “git tag”.

If you want to import further source package versions/revisions you can either run git-import-dsc in the order of their revision numbers or use ‘git-import-dscs’.

Building the package can then be done through:

  • git-buildpackage –git-pristine-tar

The ‘pristine-tar’ is important if a previous revision of this upstream version has already been uploaded to Debian. If you don’t use pristine tars then the created orig.tar.gz may be slightly different (not in content – but as an archive) from what’s already in Debian and the ftp-master will refuse your upload. If you forgot the ‘–pristine-tar’ option then at least make sure you have the orig.tar.gz in ../ that is also in Debian.

Or: Import just the orig.tar.gz into a fresh Git repository and start debianizing

  • mkdir package-name
  • cd package-name
  • git init
  • git-import-orig /path/to/orig.tar.gz
  • …work on Debian package…
  • git add debian… (or “git add .” to add everything that changed)
  • git commit
  • git-buildpackage
  • …upload to Debian… (dput/dupload)
  • git-buildpackage –git-tag

Or: package a new upstream revision

  • git-import-orig /path/to/new.orig.tar.gz

Or: pull the existing repository from your co-maintainer

  • git clone URL (for example: git clone git://git.workaround.org/cream.git)

What your co-maintainer did is in origin/upstream (the orig.tar.gz’s content) and origin/master (the debianized directory). Incidentally Git merged the origin/master into your own ‘master’ branch that you are now on. To make sure you are following the co-maintainers upstream branch, too, you’ll have to run:

  • git checkout -b upstream –track origin/upstream

The ‘–track’ option altered the .git/config file and added a [branch “upstream”] section telling Git where you fetched it from. That means you can later just say “git pull” and you will get both the ‘master’ and the ‘upstream’ repository merged into your repository automatically.

Now you will have these branches:

  • upstream (a copy of the origin/upstream – must not change)
  • master (where you do the Debian package work in just like you had no repository underneath)
  • origin/upstream (where you co-maintainer unpackaged the orig.tar.gz using git-import-orig)
  • origin/master (the debianization that your co-maintainer did so far)
  • pristine-tar (optional – information on how to build the binary-identical orig.tar.gz that is in Debian)

Work on the Debian package

  • …work…work…work…
  • git add (what you added/changed)
  • git commit
  • git-buildpackage

If you like the package:

  • …upload to Debian… (dput/dupload)
  • git-buildpackage –git-tag

And then…

Publish your own works to your public repository so that your co-maintainer can fetch what you did

The most efficient protocol to transport Git repositories and their changes is the git:// protocol. (You could also dump your repository into a web server’s htdocs directory and let others fetch it with HTTP.) 

Using git.debian.org

The Debian project is offering Git hosting at git.debian.org. You can request a new repository there through a process defined in the Debian wiki.

Using Github

Github is a nifty web service that allows hosting of Git repository. While it’s debatable that Git is actually decentralized and a central repository doesn’t make sense it’s still nice to have a place to pull and push changes. (Of course this applies to git.debian.org as well.) Repositories up to 100 MB that are public are free (beer). They also offer paid plans.

Setting up git-daemon

git-daemon is a software to serve repositories through the git:// protocol. It looks for repositories in /var/cache/git on your public (web-) server. Put up your Git repository as a “bare” repository there. (“Bare” Git repositories just consists of what’s usually in the project’s .git directory but the directory is called project.git)

This will create a copy of your repository on the ‘myserver’. “–mirror” makes it push all the branches (so you don’t miss to push the “upstream” branch) and tags (without upstream/* and debian/* tags git-buildpackage would be very unhappy).

Log into ‘myserver’, go into /var/cache/git/myproject.git and touch the file “git-daemon-export-ok” there. It tells git-daemon that this repository is allowed to be displayed publicly. (I personally prefer to change /etc/sv/git-daemon/run and add the “–export-all” option there. Because if I clone my repository into /var/cache/git I know what I’m doing and don’t accidentally put up something private there.)

To simplify pushing I recommend:

Then you can just:

  • git push

…in the future and get all your commited changes online to the public server.

Now tell your co-maintainers about it so they can “git pull git://myserver/myproject.git” from your server. Make sure you always “git pull” before you start working on the package.

Setting up gitweb (optional)

If you want to show what repositories you are offering you can run ‘gitweb’ on your web server. Just “aptitude install gitweb” on the server and follow the instructions in /usr/share/doc/gitweb/README*

See also

How do I create my own Certificate Authority (CA)

CA is short for Certificate Authority. A CA issues certificates for i.e. email accounts, web sites or Java applets. Actually this only expresses a trust relationship. If you trust the CA then you automatically trust all the certificates that have been issued by the CA. This article helps you set up your own tiny CA using the OpenSSL software.

Common web browsers already “ship” with a number of CAs. That means you usually trust companies like Verisign, AOL and Microsoft. (Do you really?) If you like to see which CAs are currently trusted:

  • Mozilla Firefox: Edit / Preferences / Advanced / Certificates / Manage Certificaes / Authorities
  • Internet Explorer: Extras / Internet options / Content / Certificates / Trusted Root CAs

Your own CA

Certificates usually do not come for free. An excellent exception is the first free CA: CaCert. Currently not all browsers have their certificate built in. Microsoft only seems to trust CAs if they pay an unrealistic amount of money – who’s surprised? It is worth spreading the word since this CA is about trust instead of money.

Otherwise having a valid certificate for your server often just means that you spend money to big companies called trust centers. But perhaps you just need a certificate (i.e. for your private web server running HTTPS at home) and do not really care whether the CA is contained in other people’s browsers. Then you should consider creating your own CA. The only difference is that your clients will get a warning when contacting your server that the CA is not (yet) trusted. This can be either safely ignored or you can make them install your CA’s certificate. It is also a good solution if you need a company-wide CA.

First you need to to install OpenSSL. On Debian this means running apt-get install openssl. Go to the directory where you want to create the files that make up the CA. Next type: /usr/lib/ssl/misc/CA.pl -newca

The script will create a new directory named demoCA. The CA’s private key (keep it safe!) and the public key/certificate (which you may need to give to your clients) will be put there. The public certificate is the demoCA/cacert.pem file. It does not matter really what you enter into the fields. Just pick a meaningful name for the common name field so that it’s clear you are looking at a CA – not a person. So name it “ACME Lasagna Certifiate Authority” instead of “Peters Blaphemic’s Fun Certificate”. Pick something that sounds official.

Notice: the CA has an expiry date. The default setting is one year. You may want to edit the file CA.pl and set Days to ten years.

Create a certificate

Now that you have your own CA you can create certificates for servers. That means you have to do two steps:

  • Your “client” creates a private key (.key) and a certificate request (.req):
    /usr/lib/ssl/misc/CA.pl -newreq

  • You sign that request with your CA’s key and create a certificate (.crt) that you send to the client:
    /usr/lib/ssl/misc/CA.pl -sign

Note: If your “client” does not send you a certificate request you can create all the necessary files for them.

To simplify things you may want to use my script makecert that you can use to quickly create new certificates for i.e. Apache SSL servers. Run it like this:

./makecert mailserver.mydomain.com

You will get three files:

  • mailserver.mydomain.com.key (the client’s private key)
  • mailserver.mydomain.com.req (the client’s certificate request)
  • mailserver.mydomain.com.crt (the client’s signed certificate)

The certificate request is just an intermediate file that is not necessary to run a server using that certificate. You just need the private key and the certificate.

If you like to use that certificate for an Apache web server you need to put the private key (.key) and the certificate (.crt) into the same file and call it apache.pem.

Example:

cat mailserver.mydomain.com.key mailserver.mydomain.crt > apache.pem

Sign a request

Some server create a certificate request (SAP, IIS). You will get that request as a file from the client. Use the following command on that request file:

ca -policy policy_anything -notext -in clients.server.com.req -days 3650 -out clients.server.com.crt

Some tricks

Show all information about a certificate:

openssl x509 -noout -text < crt

Calculate the MD5 fingerprint of a certificate:

openssl x509 -noout -fingerprint < crt

Calculate the SHA1 fingerprint of a certificate:

openssl x509 -sha1 -noout -fingerprint < crt

The ‘makecrt’ script

#
# Create SSL certificates
# Christoph Haas <email@christoph-haas.de>
#

DAYS=3650
OUTFILE=$1-apache.pem

if [ -z "$1" ]; then
echo "Usage: $0 [host.domain]"
exit 10
fi

echo "Creating certificate for host $1"

(
echo "My Country"
echo "My Region"
echo "My City"
echo "My Company"
echo "My Department"
echo $1
echo "webmaster@$1"
echo
echo
) |
openssl req -new -nodes -keyout $1.key -out $1.req -days $DAYS
openssl ca -policy policy_anything -notext -days $DAYS -out $1.crt -infiles $1.req
chmod go= $1.crt $1.key $1.req

Christoph’s OpenVPN Mini-FAQ

OpenVPN is an open-source SSL VPN software. It allows you to connect different (private) networks securely over the internet. It’s the perfect alternative to all the crappy SSL VPN appliances that the salesmen desperately try to sell. See my OpenVPN FAQ for additional questions and answers.

(This is not the official OpenVPN FAQ. It’s just my personal answers to my personal questions.)

IPs and routing

How do I assign my users fixed IP addresses?

Use ”client-config-dir” and push the IP addresses to a certain client using this line in the client-specific configuration file:

ifconfig-push 10.100.8.1 10.100.8.2

This will assign John_Doe the IP address 10.100.8.1. The other IP address is assigned to the OpenVPN server – you won’t see it there through ifconfig though.

The server also needs to route this IP (or a range) through the tunnel. So your server.conf needs to contain a route entry for all the static IPs that you will assign:

route 10.100.8.0 255.255.255.0

Which iptables rules are needed to allow OpenVPN connections?

First you need to allow UDP 1194 incoming and outgoing connections on your main interface: 

iptables -A INPUT -i eth0 -p udp --dport 1194 -j ACCEPT
iptables -A OUTPUT -o eth0 -p udp --dport 1194 -j ACCEPT

Next you need to allow certain traffic going through the tunnel. If you don’t want any restrictions then use: 

iptables -A INPUT -i tun0 -j ACCEPT
iptables -A OUTPUT -o tun0 -j ACCEPT
iptables -A FORWARD -o tun0 -j ACCEPT 

How do I make a network on the remote side of the tunnel accessible?

You need both a route and an iroute configuration directive on your server. 

iroute 192.168.152.128 255.255.255.128
route 192.168.152.128 255.255.255.128

Note: the iroute statement best belongs in the ”client-config-dir” directory. The route statement needs to be in your global server configuration file.

Also don’t forget to route that network to your OpenVPN server. The route and iroute statements will just tell OpenVPN that this network is supposed to be reached through a VPN tunnel. 

How do I let remote Windows clients browse my network?

Network browsing requires WINS to function across a router even in a full AD network. You will need to configure a WINS server and point your remote users to it.

You will also need to prevent them from assuming responsibility for maintaining the browse list. This is done with a couple of registry changes:

HKLM\System\CurrentControlSet\Services\Browser\Parameters

Make sure that IsDomainMaster and MaintainServerList are both set to FALSE.

Of course, any firewalling you are doing in the tunnel will need to allow the underlying NetBIOS traffic.

John A. Sullivan III 

Certificates 

How do I revoke a certificate?

If you want to permanently revoke access for a certain user you need to revoke the certificate that you issued. Revoking means that you list that certificate in a certificate revocation list (CRL). Once your OpenVPN server has a crl-verify option set that points to your CRL the certificates of new incoming connections will be checked against that CRL. If a certificate is listed there the access is denied. See the make-crl and revoke-full commands as part of Easy-RSA. And don’t forget to copy the new CRL to the OpenVPN server. You do not need to restart the server since the CRL is considered automatically everytime a user connects. 

Why is it bad to use static keys?

  • anyone can create an OpenVPN server and fool users (man-in-the-middle-attack)
  • you cannot revoke access for one user but need to distribute a new static key to everyone else 

Which files do I need to keep secret?

The private keys (suffix ‘.key’) need to be kept secret. The certitifcates (suffix ‘.crt’) can be exchanged freely and even sent through unsecured channels like email.

Operation 

Who is currently connected to my OpenVPN server? 

TELNET interface

Use the TELNET interface and issue a status command. 

Status file

Add these lines to your server configuration file: 

status status.log 5
status-version 2

This will write the current status of the OpenVPN server to the given logfile every 5 seconds in the configuration directory. Lines starting with CLIENT_LIST show you the connected users.

If you like to collect statistics on how many users are online at a given time (MRTG creates nice graphs) you can use this one-liner: 

grep ^CLIENT_LIST /etc/openvpn/status.log | wc -l 

How can I disconnect a client from the OpenVPN server?

Use the TELNET interface and issue a kill command on the common name of the client. The client will be able to reconnect though unless you revoke its certificate. Killing a client may be useful if you have changed a configuration file in the client-config-dir.

Do I have to restart OpenVPN after every configuration change?

Changes to the global configuration file (e.g. /etc/openvpn/server.conf) require a restart of the OpenVPN service. Consider using the ”client-config-dir” option to set client-specific parameters. Such configuration files will be read when a client connects and do not require a restart.

From time to time you will need to restart the server e.g. if you need to add a route entry. Consider adding this lien to your server configuration though: 

keepalive 1 5
persist-tun
persist-key
persist-local-ip
persist-remote-ip
push "persist-key"
push "persist-tun"

It will make the client send a "ping" to the server every second. If there is no reply to that "ping" after 5 seconds then the connection will be re-initiated. The default connection timeout is very large and will surely annoy your users. If they get disconnected for less than 10 seconds they will complain less likely. The persist-* settings will make the client keep the tunnel device open so existing connections won’t be interrupted during the renegotiation. Otherwise permanent connections like shell sessions would be disconnected.

How do I use the ‘client-config-dir’ parameter?

The client config directory is a location where you put custom client-specific configuration files. Example in your global configuration (e.g. /etc/openvpn/server.conf):

client-config-dir /etc/openvpn/clients

Then put files with the common names of your users there. The common name must match the filename exactly. Let’s pretend you have a user with the common name "John_Doe" on his certificate. Create a file /etc/openvpn/clients/John_Doe and make it contain configuration directives that should only apply to John Doe. The following directives are allowed there:

  • push
  • push-reset
  • iroute
  • ifconfig-push
  • config

Example /etc/openvpn/clients/John_Doe:

iroute 112.12.58.128 255.255.255.240
ifconfig-push 10.100.8.1 10.100.8.2

This will assign John Doe the IP 10.100.8.1 on his side of the VPN tunnel. Also the server will learn that the network 112.12.58.128/28 is on John’s side of the VPN tunnel and route packets there. (Note that you also need to create a "route 112.12.58.128 255.255.255.240" in your global configuration to make the OpenVPN server learn this route. The "route" command does not work within a client-config-dir configuration file.)

The charming advantage of client-config-dir configurations is that you don’t need to restart your OpenVPN server to make changes to these files work. Every time a client connects the client-config-dir will be searched for an appropriate file and if one is found the configuration will be applied.

There is also a special DEFAULT file that contains settings in case there is no configuration file for a certain client.

How can I access the TELNET management console?

You need to start OpenVPN with the --management option. For example --management 127.0.0.1 12345 as a startup parameter will get you access to the TELNET console on port 12345 on localhost. Accessing the console then is as easy as telnet localhost 12345. This is what you get:

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
>INFO:OpenVPN Management Interface Version 1 -- type 'help' for more info

This is a security risk though because everybody can access the console without any further authentication.

Interoperability

Does OpenVPN work with Juniper/Nortel/Checkpoint VPNs?

No. OpenVPN just works with other OpenVPN clients/servers. OpenVPN is not an IPSEC software. It uses SSL to create VPN tunnels instead.

© 2021 workaround.org - Proudly powered by theme Octo