In this lecture Uncle Bob talks about some common OO patterns and breifly connects the history of OO design ideas. I can just smell the ports-and-adapters!
Full video:
What services are using ipv6 on the server? None! Sounds like a potential security issue. These notes cover disabling ipv6 on Debian Wheezy.
Edit /etc/sysctl.conf and add those parameters to kernel. Also be sure to add extra lines for other network interfaces you want to disable IPv6.
Better yet, create file in /etc/sysctl.d/disable-ipv6.conf with those values
Comment out all the IPV6 hosts in /etc/hosts
Add GRUB_CMDLINE_LINUX_DEFAULT=”ipv6.disable=1 quiet” to /etc/default/grub (grub2)
– for Xen domU add to /boot/grub/menu.lst
You have to reboot the system to make changes take effect.
### IMPORTANT: after editing /etc/default/grub you have to execute “update-grub”
For postfix you have to edit /etc/postfix/main.cf and change (or add) b/c by default it uses both ipv4 and ipv6 and you’ll get warnings on reload of postfix unless you put this
inet_protocols = ipv4
Edit exim4 settings or you’ll get entries in the exim4 paniclog.
Edit /etc/exim4/update-exim4.conf.conf add a new line
disable_ipv6='true'
and remove the ipv6 stuff from dc_local_interfaces line then execute update-exim4.conf and service exim4 restart.
This post describes how to get SELinux running on a Xen guest (domU) that is running Debian Wheezy.
First, you need a guest that is booted by pvgrub and running a distro-supplied kernel ie, a regular (non-Xen) linux image. All that is convered in my previous post on booting unprivileged domains in Xen with pvgrub on Debian Wheezy. This is a required step.
Next we’ll follow Debian’s own SELinux set up, mostly.
You need to install some packages, but I left out some dependencies in particular that I didn’t want so I used –no-install-recommends.
apt-get –no-install-recommends install selinux-basics selinux-policy-default auditd audispd-plugins
In /etc/default/rcS change
set FSCKFIX=yes
I ran selinux-activate, but it doesn’t do what it is supposed to do. So you have to fix these issues by hand.
Add kernel options to enable SELinux in /boot/grub/menu.lst, mine looks like this:
kernel /vmlinuz root=/dev/xvda1 ro selinux=1 security=selinux
Fix pam by adding to /etc/pam.d/login
session required pam_selinux.so multiple
Touch /.autorelabel
Restart the guest. I use xm create -c /path/to/guest/config so I get the console and can watch for relabelling to occur. After relabelling the system should reboot, but it doesn’t. It shuts down and doesn’t come back up. So I xm create -c /path/to/guest/config again. Once I logged in to the guest I ran sestatus and got
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: default
Current mode: permissive
Mode from config file: permissive
Policy MLS status: enabled
Policy deny_unknown status: denied
Max kernel policy version: 26
The main issues with Debian’s own SELinux how-to are 1) selinux-activate does not do what it is supposed to in Wheezy 2) we add the kernel options to enable SELinux in /boot/grub/menu.lst.
Also, at somepoint I had to remove a file, but I can’t find the info that I used to justify that step. Here is it:
rm -i /etc/udev/rules.d/010-no-legacy-ptys.rules
Goal:
Have guest domains boot with their own kernel, or in other words, be able to run a kernel different than the host. Moreover, this means maintainer of the guest can be responsible for dealing with kernel updates. You can do this with pygrub, but there are reasons you may want to use pvgrub. Note the very minor difference in the spelling of the names! Note: both pygrub and pvgrub are for paravirtualized guests. So if you’re using hardware virtualization, this isn’t for you. Pygrub is named because is a python script. Pvgrub stands for paravirtualized grub.
Caveats:
Turns out there are some special steps in Debian Wheezy and here’s how I got it working along with reference article I used to figure it out.
These are the required steps and I’ll go into detail on each of the below.
Morale Booster:
In this instance the host is Debian Wheezy running Xen 4.1.4 (for reference).
There is no pvgrub in Debian, so you have to get it from somewhere else. In this case I actually grabbed the _current_ xen release from github and compiled it. This creates the pvgrub images. I was concerned the pvgrub image would not work wtih 4.1.4 but it did, so I’m happy (for now).
The xen.org wiki was the main source where I got this information from and this should be considered a supplement to that article, not a replacement.
Before compiling xen I also needed the following packages in addition to all of the ones lists in the xen wiki post:
libaio-dev
texinfo
Here’s the part that wasn’t clear to me: pvgrub goes on the host, much like pygrub is run from the host. Duh! But that didn’t occur to me at first. So put pvgrub image on your host.
So to complete step #1 install pvgrub on the host you need to:
1) install any of these packages if you don’t already have them:
python-dev gettext bin86 bcc iasl uuid-dev libncurses5-dev pkg-config libglib2.0-dev libyajl-dev libpixman-1-dev bzip2 libc6-dev-i386 libaio-dev texinfo
2) git the xen source:
git clone git://xenbits.xen.org/xen
3) compile xen:
./configure
make
The pvgrub images are gz files in dist/install/usr/local/lib/xen/boot and they are
pv-grub-x86_32.gz
pv-grub-x86_64.gz
and you’ll need the correct one depending on what the guest machine is going to run. My guests are all x86_64. As a side note: I didn’t even compile xen on the host, I did it on another machine running Debian Wheezy then copied over the files I wanted.
4) Copy the pvgrub images to the host machine, in my case I use only amd64 flavors for host and all guests, so I just copied that one to /usr/local/lib/pv-grub-x86_64.gz Made sure its owned by root and permissions are 0644.
To complete step #2 – Install Linux images on guest:
1) on the guest install a linux image of your choosing
2) create /boot/grub/menu.lst with these contents
default 0
timeout 2
title Debian GNU/Linux
root (hd0)
kernel /vmlinuz root=/dev/xvda1 ro
initrd /initrd.img
title Debian GNU/Linux (recovery mode)
root (hd0)
kernel /vmlinuz root=/dev/xvda1 ro single
initrd /initrd.img
where /vmlinuz is a symlink to the kernel image you installed. In my case the guest disk is not partitioned, otherwise the (hd0) would be (hd0,0).
Create /etc/modprobe.conf with contents. Why? Because xen wiki article says to.
alias eth0 xennet
alias scsi_hostadapter xenblk
Likewise update /etc/inittab per xen wiki article:
hvc0:2345:respawn:/sbin/getty 38400 hvc0
xvc0:2345:respawn:/sbin/getty 38400 xvc0
Now we are ready to complete step #3, telling the host how we are going to boot the guest by editing the guest’s configuration file. These are the lines you need in the configuration file:
# points to PVgrub on host (dom0)
kernel = '/usr/local/lib/pv-grub-x86_64.gz'
# location of menu.lst on domU
extra = '(hd0)/boot/grub/menu.lst'
Please note the is usually an entry something like
root = '/dev/xvda1 ro'
in the guest’s configuration file. Remove it! Otherwise when you create the guest you’ll get dumped out on at a grub prompt. I just commented it out.
Now you can halt the guest and then
xm create -c /path/to/guest/config/file
to start the guest, with any luck.
Final thoughts…I’ve not dealt with this yet but the original author suggests making a symlink to /boot/grub/grub.cfg from /boot/grub/menu.lst so updates that use grub.cfg don’t freak out.
Using jQuery:
function check_for_duplicate_ids() { // iterator over every element on page w/ id attribute set $('[id]').each(function(){ // find all elements on page by id where id is this.id var ids = $('[id="'+this.id+'"]'); if(ids.length>1 && ids[0]==this) { // we have more than 1 id and the id is same as // element we are iterating over console.warn('Multiple IDs #'+this.id); } }); }
A range of IP addresses can be expressed very simply with CIDR notation. I don’t want to discuss why classless inter-domain routing was developed, but only demonstrate how you can figure out what the CIDR notation for a range of IP addresses, or determine what the range of IP addresses are represented by a CIDR notation.
Consider the following IP address: 192.168.0.1
The IP address (IPv4 is only discussed in this CIDR tutorial) is made up of four octets. The first one is 192 which in binary notation would be 1100 0000 and I’ve written here with a space to make reading easier. In binary each 1 represents a value depending on which bit in the byte it is. Here are the values from left to right:
128 64 32 16 8 4 2 1
So 1100 0000 in binary is equal to 128 + 64 in decimal, or 192. If we write out the binary representation for each octet:
192.168.0.1
1100 0000 – 1010 1000 – 0000 0000 – 0000 0001
CIDR notation looks like an IP address followed by a slash with a number, for example:
192.168.0.0/24
The number after the slash is the bit mask for the network. Simply put, it tells us how many bits are the same for each IP on the subnet. This also tells us which parts of the IP addresses can vary, and that gives us the range.
192.168.0.0/24 indicates that the first 24 bits are all the same on this range of IP addresses. Lets look at the first 24 bits:
1100 0000 – 1010 1000 – 0000 0000
That is the first 24 bits of 192.168.0.0. This means the remaining 8 bits can be either 0 or 1, but on this range of IP addresses the first 24 bits will always be the same.
If we set the part that can be 0 or 1 to all 1’s we can get the maximum IP value on the range:
1100 0000 – 1010 1000 – 0000 0000 – 1111 1111
All 1’s is 255, so the maximum IP on this range is 192.168.0.255.
The CIDR notation for the range of IP addresses from 192.168.0.0 thru 192.168.0.255 is thus 192.168.0.0/24.
Here is another range of IP addresses: 128.1.0.1 thru 191.255.255.254. How can this range of IP addresses be written in CIDR notation?
128.1.0.1 can be written in binary as
1000 0000 – 0000 0001 – 0000 0000 – 0000 0001
191.255.255.254 can be written as
1011 1111 – 1111 1111 – 1111 1111 – 1111 1110
We can see that the bits that are the same in this range, starting with the left most octet are
10
So there are only 2 bits in the mask, making the CIDR notation:
128.1.0.1/2
Here is another example of calculating the CIDR notation for a range of IP addresses:
69.4.128.0 – 69.4.159.255
Writing each IP in binary form we have
0100 0101 – 0000 0100 – 1000 0000 – 0000 0000
0100 0101 – 0000 0100 – 1001 1111 – 1111 1111
So we can see the bit mask, which is the left most set of bits that are the same are
0100 0101 – 0000 0100 – 100
which is 19 bits, so this range of IP addressed can be expressed in CIDR notation as
69.4.128.0/19
Hopefully this CIDR notation tutorial can help you quickly determine the CIDR notation for a given range of IP addresses, or how to determine the range if IP addresses represented by CIDR notation.
When code runs without a user interface, for example a script invoked by cron, there often is not an easy way to see what errors are occuring. Another example would be php invoking another php script using exec(), for example. Here are some common fatal errors: unknown class referenced, unknown method called and parse error. Forgot a semicolon? Thats a parse error.
This post combines ideas others have used and gives an example of how to capture and log fatal php errors.
The php function set_error_handler() allows you to create a callback for handling errors. However, you cannot catch fatal errors using a callback registered with set_error_handler().
You can register a callback for php to invoke at the very end of execution via register_shutdown_function(). There is a way to see if there were any errors during script execution by calling error_get_last().
The problem is, how do we call register_shutdown_function()? If the script you want to monitor for errors has en error, like a parse error, and you put the register_shutdown_function() call in that script it will not work, because of the parse error. And using “include” or “require” will not work either because that essentially is still the same script, as far as php is concerned.
You can however use an INI file to tell php to automatically prepend a php file before invoking the script you want to monitor. By combining this with the log4php as the logging library you can create a very powerful error handler. You can read my log4php how-to if you are not familiar with the log4php library.
Imagine this is the script to be called by cron, it has a parse error. The code is saved in a file called mycron.php.
<?php
$foo = ;
?>
I put mycron.php in its own directory: /home/tom/bin.
In that same directory create php.ini telling php what files to automatically prepand and append:
; php.ini contents: auto_prepend_file = /home/tom/bin/runtime_start.php
The contents of runtime_start.php is:
<?php require_once 'log4php/Logger.php'; Logger::configure('logconfig.xml'); class Runtime { function Runtime() { register_shutdown_function(array($this, 'shutdown')); } function shutdown() { $logger = Logger::getLogger('root'); $e = error_get_last(); if(is_null($e)) { $logger->debug('Script ended normally'); } else { $logger->error($e['message']); } } function finish() { $logger = Logger::getLogger('root'); $logger->debug('Script ended normally'); } } $runtime = new Runtime(); ?>
One of the nice things about this approach is that the script I’m executing does not have to be altered in any way to add the error capturing and logging. You do however need to invoke it in a particular way. You have to tell php where to find the INI file:
php -c /home/tom/bin -f /home/tom/bin/mycron.php
You can get the full list of php command line invocation options using “php –help”.
When run the log file will contain a message like the following:
2011-09-15 11:08:01 PDT [ERROR] root: syntax error, unexpected ‘:’