OpenVPN setup on Centos 5.2
August 10th, 2008 by laneOpenVPN is a very capable SSL-based VPN client/server software package. It has great documentation at
OpenVPN Howto Documents.
-
To install on CentOS, I grab the rpms from the EPEL repo. EPEL stands for Extra Packages for Enterprise Linux. They are Fedora packages repackaged for Redhat Enterprise. The project homepage and documentation is at http://fedoraproject.org/wiki/EPEL. There is also a package list at that site.
To install the EPEL yum repo, run the following command:sudo rpm -ihv http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-2.noarch.rpm
Change the architecture and version appropriately for your machine.
- Install OpenVPN with the following command:
yum install openvpn
- For now I will setup OpenVPN to route rather than bridge. Later I will likely bridge two remote networks.
- Generate the Master Certificate Authority. Copy the templates files into place:
sudo cp -r /usr/share/openvpn/easy-rsa/2.0 /etc/openvpn/certs
Now
cdinto/etc/openvpn/certsand edit thevarfile. The only thing I changed was the last five lines containing the location information. Now run the following commandssudo su . ./vars ./clean-all ./build-ca
Note that you want to be root when running these commands because the
varsscript alters your environment, and they will get lost if you are usingsudoon each command individually. - Generate certificate & key for server.
./build-key-server server_name
I left challenge password empty and answered yes to signing and committing the certificate.
- Generate client certificates
./build-key client1
- Build Diffie Hellman data
./build-dh
- You can now drop root permissions and setup the server configuration file
sudo cp /usr/share/doc/openvpn-2.1/sample-config-files/server.conf /etc/openvpn
Edit it to your liking. I did not change much except to add paths appropriately to the certificate and dh files.
- Install OpenVPN on the client.
yum install openvon
. In my case this a Fedora 9 machine.
-
sudo cp /usr/share/doc/openvpn-2.1/sample-config-files/client.conf /etc/openvpn/
and edit it to your liking.
- Copy the keys from the server to the client and start it up
- For routing so that I run the following
echo 1 > /proc/sys/net/ipv4/ip_forward
on the server so that machines on the same subnet as the server can talk to the clients. Likewise, I add the following static route to the default gateway (which is my wireless router):
Destination LAN IP: 10.8.0.0 Subnet Mask: 255.255.255.0 Gateway: 192.168.35.2
where gateway is the IP of the vpn server.
LVM Example
July 28th, 2008 by laneI always look at the MythTV documentation for a short, quick LVM reference
I have a large 2TB RAID 5 device that I want to split into two partitions. LVM gives that ability. Here are the steps I followed:
- Create the physical group
sudo pvcreate /dev/md0
- Create the volume to include the whole physical group.
vgcreate bigdisk /dev/md0
- Then use
lvcreateas follows:sudo lvcreate --name mm --size 1TB bigdisk sudo lvcreate --name home -l 214789 bigdisk
Example Software RAID 5 Setup in Linux
July 28th, 2008 by laneI have three identical 1TB hard drives that I want to configure in a RAID 5 configuration to give me 2 TB. A good resource is RAID Quick HOWTO. Here are the steps I took:
- Create partitions on the desired devices to have a type of 0xFD (linux raid autodetect). I created a single 1TB partition on each drive using fdisk.
- Create the raid device using
mdadmcommandsudo mdadm --create --verbose --level=5 --raid-devices=3 /dev/md0 /dev/sda1 /dev/sdc1 /dev/sdd1
The output for me looks like this:
mdadm: layout defaults to left-symmetric
mdadm: chunk size defaults to 64K
mdadm: /dev/sdc1 appears to be part of a raid array:
level=raid5 devices=2 ctime=Mon Jul 28 09:09:11 2008
mdadm: /dev/sdd1 appears to be part of a raid array:
level=raid5 devices=2 ctime=Mon Jul 28 09:09:11 2008
mdadm: size set to 976759936K
Continue creating array? y
mdadm: array /dev/md0 started.
/proc/mdstat file to see how things went. For me, it looks likethis
$ cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4]
md0 : active raid5 sdd1[3] sdc1[1] sda1[0]
1953519872 blocks level 5, 64k chunk, algorithm 2 [3/2] [UU_]
[>....................] recovery = 0.0% (55552/976759936) finish=1171.1min speed=13888K/sec
unused devices:
/etc/mdadm.conf file.
mdadm --detail --scan --verbose > /etc/mdadm.conf
mdadm to monitor the array and send an email if anything fails. I add the following line to my /etc/rc.local file:
/sbin/mdadm --monitor -t -f -d 3600 -y --scan -m lane@brooks.nu
The -t option causes a test message to be sent when the command is first run. This lets you verify the notification path. The -f puts the process in the background. -d 3600 puts the polling rate at once every hour. -y causes events to get logged to the syslog.
You will get a DegradedArray array when you first setup the raid and it is doing the initial build of the array (which can take some time if you have big disks). This is to be expected as the array is not finished building.
/proc/mdstat at any time to see the state of your devices. It will tell if one has failed.Gray Coding
July 25th, 2008 by laneThe schematic for gray coding and back to binary is shown in the figure below.
Below are two verilog functions to implement this logic. They are made functions for ease of instancing.
function [ADDR_WIDTH-1:0] bin2gray;
input [ADDR_WIDTH-1:0] x;
begin
bin2gray = x ^ (x>>1);
end
endfunction
function [ADDR_WIDTH-1:0] gray2bin;
input [ADDR_WIDTH-1:0] x;
integer i;
begin
gray2bin[ADDR_WIDTH-1] = x[ADDR_WIDTH-1];
for(i=ADDR_WIDTH-2; i>=0; i=i-1) begin
gray2bin[i] = gray2bin[i+1] ^ x[i];
end
end
endfunction
Following is a simple module for testing these functions:
module graytest
(input clk,
input resetn
);
parameter ADDR_WIDTH=3;
reg [ADDR_WIDTH-1:0] count;
wire [ADDR_WIDTH-1:0] gcount = bin2gray(count);
wire [ADDR_WIDTH-1:0] bcount = gray2bin(gcount);
always @ (posedge clk or negedge resetn) begin
if(~resetn) begin
count <= 0;
end else begin
$display("0b%b -> 0b%b -> 0b%b", count, gcount, bcount);
count <= count + 1;
end
end
function [ADDR_WIDTH-1:0] bin2gray;
input [ADDR_WIDTH-1:0] x;
begin
bin2gray = x ^ (x>>1);
end
endfunction
function [ADDR_WIDTH-1:0] gray2bin;
input [ADDR_WIDTH-1:0] x;
integer i;
begin
gray2bin[ADDR_WIDTH-1] = x[ADDR_WIDTH-1];
for(i=ADDR_WIDTH-2; i>=0; i=i-1) begin
gray2bin[i] = gray2bin[i+1] ^ x[i];
end
end
endfunction
endmodule
When I run this simulation (using verilator), I get the following output:
0b000 -> 0b000 -> 0b000 0b001 -> 0b001 -> 0b001 0b010 -> 0b011 -> 0b010 0b011 -> 0b010 -> 0b011 0b100 -> 0b110 -> 0b100 0b101 -> 0b111 -> 0b101 0b110 -> 0b101 -> 0b110 0b111 -> 0b100 -> 0b111
The left-most column is a 3 bit number from a binary counter. The middle column is the gray encoded value of this counter, and the right column is the gray2bin output. This verifies that it works. Here is a picture of the simulation results:

Dynamic method creation in python
June 26th, 2008 by laneI recently wrote some python bindings for a third party, closed source shared library. This library was a USB communication API to a board made by Opal Kelly. I was writing a multi threaded python application for video streaming. The video stream went through the shared library on a worker thread. The GUI thread, however, also had access to the shared library giving the user the ability to change settings while the thread was running. The shared library was not thread safe, however, the global interpreter lock kept things safe. I found the global interpreter lock when trying to figure out why the video stream through this shared library was so slow and choppy. The reason was that the streaming thread would not context switch while waiting on I/O. After adding the Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS macros around my I/O calls, my video stream started behaving nicely, but now I had a thread safety issue because the GUI thread could now access the shared library while the capture thread was waiting on I/O.
To solve this, I wanted to wrap the python bindings in a class that would use a mutex to lock access to every function in the shared library. I did not want to have individually wrap each function call either. So I used the __getattribute__ function to globally wrap each function like this:
class FrontPanelThreadSafe(ok.FrontPanel):
"""This class wraps up the ok.FrontPanel to make it thread safe by
creating a lock that must be acquired before any function call in
the base class can be called."""
def __init__(self):
ok.FrontPanel.__init__(self)
self.lock = threading.Lock()
def __getattribute__(self, key):
"""This function does all the magic. All function calls to
this object go through this method. This method passes them
on to the base class after it acquires the lock to make the
access to the opal kelly board atomic."""
if(key == "lock"):
return object.__getattribute__(self, key)
else:
def func(*args, **kw):
try:
self.lock.acquire()
return ok.FrontPanel.__getattribute__(self, key)(*args, **kw)
finally:
self.lock.release()
return func
Fortunately, right now the base class does not have any attributes–just methods. If it had attributes, then I would need to add a condition to distinguish the two.
Elan USBscope50 on Fedora 8
June 3rd, 2008 by laneI have wanted a USB scope for quite some time now, and even considered designing my own. Well the other day I set out to find one with linux support and found one made by Elan Digital Systems. While $400 is way too expensive for such a device, it is much cheaper than a stand alone option, so I decided to try it out. It is a bit strange that it does not come with a probe, so I ordered a probe separately from Digikey. I need two channel support, but appearantly the Linux software does not yet support multiple channels, so I just bought one channel for now to evaluate it.
The installation procedure that I used is below. Overall the installation process was fine. They do not provide udev rules and say to run the program as root. This is bad. Follow my rules to avoid this. The java application is listed as Beta, and it is missing quite a bit of functionality. So much so that I booted my laptop into windows to try their windows version. It is a lot more complete and usabe.
Installation Instructions
Fedora 8 kernel has the Elan device support, so it is not necessary to recompile the kernel. I plugged it in and the red LED came on without any changes.
- First setup the
udevrules so that you do not need to be root to access the Elan device. The followingudevrules placed in a file called/etc/udev/rules.d/60-elan.rulesdirectory worked for me# give all ttyUSB devices rw permission to all KERNEL=="ttyUSB*", MODE="0666"
Run
udevcontrol reload_rulesas root after adding the rules. -
Now plug the elan device in, run
lsusb(part of theusbutilspackage) and see the addition of the Elan scope with this line:Bus 002 Device 002: ID 10c4:f001 Cygnal Integrated Products, Inc.
- Look to ensure that
/proc/bus/usb/devicescontains the following listing:T: Bus=02 Lev=01 Prnt=01 Port=07 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=10c4 ProdID=f001 Rev= 1.06 S: Manufacturer=Silicon Labs S: Product=USBscope50 S: SerialNumber=K58159-002 C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=200mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=cp2101 E: Ad=81(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
-
And look at
/var/log/messagesfor a similar message:May 29 10:42:18 XXXX kernel: usb 2-8: new full speed USB device using ohci_hcd and address 2 May 29 10:42:18 XXXX kernel: usb 2-8: configuration #1 chosen from 1 choice May 29 10:42:18 XXXX kernel: cp2101 2-8:1.0: cp2101 converter detected May 29 10:42:18 XXXX kernel: usb 2-8: reset full speed USB device using ohci_hcd and address 2 May 29 10:42:18 XXXX kernel: usb 2-8: cp2101 converter now attached to ttyUSB0
- Check the permissions of the device using
ls -al /dev/ttyUSB0. This will verify that yourudevrules are working.crw-rw-rw- 1 root uucp 188, 0 2008-05-29 11:03 /dev/ttyUSB0
- Now install the Elan software. I ran the following commands to download and install
wget http://www.elandigitalsystems.co.uk/support/usbtmfaq/usbscope50/usbscope50_java_beta_linux_setup.zip mkdir usbscope50 cd usbscope50 unzip ../usbscope50_java_beta_linux_setup.zip sudo cp USBscope50Drvr.so /usr/lib
- Try running the software (while in the same directory)
java -jar USBscope50_Software.jar
- On a 32 bit machine, I initially got this error:
Exception in thread "main" java.lang.NoClassDefFoundError: de.javasoft.plaf.synthetica.SyntheticaLookAndFeel at java.lang.Class.initializeClass(libgcj.so.8rh) at java.lang.Class.initializeClass(libgcj.so.8rh) at usbscope50software.USBFamily_Main.main(USBFamily_Main.java:304) Caused by: java.lang.ClassNotFoundException: sun.swing.DefaultLookup not found in gnu.gcj.runtime.SystemClassLoader{urls=[file:USBscope50_Software.jar], parent=gnu.gcj.runtime.ExtensionClassLoader{urls=[], parent=null}} at java.net.URLClassLoader.findClass(libgcj.so.8rh) at gnu.gcj.runtime.SystemClassLoader.findClass(libgcj.so.8rh) at java.lang.ClassLoader.loadClass(libgcj.so.8rh) at java.lang.ClassLoader.loadClass(libgcj.so.8rh) at java.lang.Class.initializeClass(libgcj.so.8rh) ...2 moreSo I installed the icedtea version of java with the following command:
yum install java-1.7.0-icedtea
Then the application at least launched, but the signal was a constant flat line zero. So I installed Sun’s JRE, and then things started working.
- On a 64 bit machine I got this error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: /usr/lib/USBscope50Drvr.so: /usr/lib/USBscope50Drvr.so: wrong ELF class: ELFCLASS32 (Possible cause: architecture word width mismatch) at java.lang.ClassLoader$NativeLibrary.load(Native Method) at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1769) at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1665) at java.lang.Runtime.load0(Runtime.java:788) at java.lang.System.load(System.java:1042) at usbscope50software.LoadDataArray.(LoadDataArray.java:600) at usbscope50software.USBscope50_Main. (USBscope50_Main.java:145) at usbscope50software.USBFamily_Main. (USBFamily_Main.java:108) at usbscope50software.USBFamily_Main.main(USBFamily_Main.java:310) It seems Elan needs a 64 bit release of their shared library.
linux gpib on Fedora 5 with swig’d python bindings - National Instraments USB HS card
April 6th, 2008 by lane- Download linux-gpib version 3.2.10 from http://linux-gpib.sourceforge.net
- Build the linux-gpib software
./configure --disable-guile-binding --disable-perl-binding --disable-php-binding --disable-python-binding --disable-tcl-binding --prefix=/usr make sudo make install
- Created a file
/etc/udev/rules.d/60-gpib.ruleswith the following contentsBUS=="usb", SYSFS{idVendor}=="3923", MODE="0666", RUN+="/usr/sbin/gpib_config" KERNEL="gpib[0-9]*", MODE="0666"I found that the kernel was oops’ing with these udev lines, so I commented out the first line that runs gpib_config and then manually run gpib_config. My guess is that the device needs some time to come on-line and that a delay is necessary. I am not sure how to force udev to wait though.
- Reload the udev rules
sudo udevcontrol reload_rules
- Create
/etc/gpib.confas follows:interface { minor = 0 board_type = "ni_usb_b" name = "usb" pad = 0 sad = 0 timeout = T3s master = yes } - From the manual
Unlike the USB-B, the USB-HS does not require a firmware upload to become functional after being
plugged in. The linux-gpib tarball contains hotplug scripts which will automatically run gpib_config
after the device is plugged in. - Unpack this tar file in the
languagessubdirectory swig’d linux gpib. - cd into the py_swig directory. run
makeandmake install - Now you can import gpib in python
- Here is some examples of how to use it
import gpib class hp34401A: def __init__(self, addr, minor=0, timeout=11): self.ud = gpib.ibdev(minor, addr, 0, timeout, 1, 0) if(self.ud < 0): raise RuntimeError("Error creating hp8656B") def meas(self): gpib.ibWrt(self.ud, "RST*"); gpib.ibWrt(self.ud, "MEAS:VOLT:DC?"); status, data = gpib.ibRd(self.ud); if(gpib.ThreadIberr()): raise Exception("Read error: status = 0x%x" % status) else: print data[:gpib.ThreadIbcnt()] return float(data[:gpib.ThreadIbcnt()]) class hp8656B: def __init__(self, addr, minor=0, timeout=11): self.ud = gpib.ibdev(minor, addr, 0, timeout, 1, 0) if(self.ud < 0): raise RuntimeError("Error creating hp8656B") def setFreq(self, freq): # 9 digits max gpib.ibWrt(self.ud, "FR"+str(freq)+"MZ") def setAmpl(self, ampl): # 9 digits max gpib.ibWrt(self.ud, "AP"+str(ampl)+"VL") class hp8644B: def __init__(self, addr, minor=0, timeout=11): self.ud = gpib.ibdev(minor, addr, 0, timeout, 1, 0) if(self.ud < 0): raise RuntimeError("Error creating hp8656B") def setFreq(self, freq): # 9 digits max gpib.ibWrt(self.ud, "FR"+str(freq)+"MZ") def setAmpl(self, ampl): # 9 digits max gpib.ibWrt(self.ud, "AP"+str(ampl)+"VL") if __name__ == "__main__": hp = hp34401A(12)
exim rewrite subject based on spam
March 26th, 2008 by laneHere is how I got exim to rewrite the Subject header after spamassassin marks a message as spam.
I have an spam ACL in my /etc/exim/exim.conf as follows:
warn spam = spam/defer_ok
add_header = X-Spam-Flag: YES
This will add the X-Spam-Flag: YES header to the email, but I also want to append *** SPAM *** to the Subject :. The way I got this working was to use a filter. Before the begin ACL section of the /etc/exim/exim.conf file, I added the following line:
system_filter = /etc/exim/spam.filter
Then I created a /etc/exim/spam.filter file with the following contents:
if $header_X-Spam-Flag: contains "YES" then headers add "Old-Subject: $h_subject:" headers remove "Subject" headers add "Subject: *** SPAM *** $h_old-subject" headers remove "Old-Subject" endif
cyrus imap folder seen state problems
March 26th, 2008 by laneI had a user with a problem where squirrelmail would not let him click on his INBOX. In thunderbird he would mark all the messages in his INBOX as read, but that would not stick so that the next time he logged in they would all be marked unread again. I looked in the /var/logs/maillog log file and found these messages:
Mar 26 23:21:12 imaps[30634]: DBERROR: skiplist recovery /var/lib/imap/user/b/buser.seen: ADD at 2FC0 exists Mar 26 23:21:12 imaps[30634]: DBERROR: opening /var/lib/imap/user/b/buser.seen: cyrusdb error Mar 26 23:21:12 imaps[30634]: Could not open seen state for buser (System I/O error)
Without stopping the cyrus-imap server, I cd’d into the directory above, deleted the buser.seen file, and everything started working again.


