October 20, 2015

gvim on Windows: how to set font to GB2312

The Windows version of VIM that I am using is the Win-32 console and OLE GVIM flavor.  Assuming you took the defaults during the installation of the program, you will find the VIM init file in the %DRIVE%\Program Files\Vim called _vimrc.  Edit this file and add a line that looks like the following:
set guifont=Lucida_Console:h10
This will use the Lucida Console font in size 10 regular.  You can use other fonts, sizes and settings. The syntax is basically:
set guifont=font-family:size:style
Here is a snippet from the VIM help guide:
 For the Win32 GUI     *E244* *E245*
 - takes these options in the font name:
  hXX - height is XX (points, can be floating-point)
  wXX - width is XX (points, can be floating-point)
  b   - bold
  i   - italic
  u   - underline
  s   - strikeout
  cXX - character set XX. valid charsets are: ANSI, ARABIC,
        BALTIC, CHINESEBIG5, DEFAULT, EASTEUROPE, GB2312, GREEK,
        HANGEUL, HEBREW, JOHAB, MAC, OEM, RUSSIAN, SHIFTJIS,
        SYMBOL, THAI, TURKISH, VIETNAMESE ANSI and BALTIC.

   Use a ':' to separate the options.
 - A '_' can be used in the place of a space, so you don't need to use
   backslashes to escape the spaces.
 - Examples:
     :set guifont=courier_new:h12:w5:b:cRUSSIAN
     :set guifont=Andale_Mono:h7.5:w4.5

October 17, 2015

Ubunut 14.04 install Strongswan IKE2 for Windows 7

1. sudo apt-get install strongswan  strongswan-plugin-eap-mschapv2
2. generate certificates using the following commands (change vpn.example.com to your actual domain name or IP address) (Source: http://serverfault.com/questions/536092/strongswan-ikev2-windows-7-agile-vpn-what-is-causing-error-13801)
ipsec pki --gen --type rsa --size 4096 --outform pem > vpnca.key.pem
ipsec pki --self --flag serverAuth --in vpnca.key.pem --type rsa --digest sha1 \
    --dn "C=US, O=Example Company, CN=Example VPN CA" --ca > vpnca.crt.der
ipsec pki --gen --type rsa --size 4096 --outform pem > vpn.example.com.key.pem
ipsec pki --pub --in vpn.example.com.key.pem --type rsa > vpn.example.com.csr
ipsec pki --issue --cacert vpnca.crt.der --cakey vpnca.key.pem --digest sha1 \
    --dn "C=US, O=Example Company, CN=vpn.example.com" \
    --san "vpn.example.com" --flag serverAuth --outform pem \
    < vpn.example.com.csr > vpn.example.com.crt.pem 
openssl rsa -in vpn.example.com.key.pem -out vpn.example.com.key.der -outform DER

sudo cp vpnca.crt.der /etc/ipsec.d/cacerts
sudo cp vpn.example.com.crt.pem /etc/ipsec.d/certs
sudo cp vpn.example.com.key.der /etc/ipsec.d/private

3. import the above vpnca.crt.der file to your windows certificate store (as CER file). To install the trusted CA certificate locally, call up the Microsoft Management Console (mmc) and add the Certificates Snap-In. Then, It is of the utmost importance that you select Computer account, Go into the Certificates (Local Computer) / Trusted Root Certification Authorities / Certificates folder,and select the Import action which will start the Certificate Import Wizard (https://wiki.strongswan.org/projects/strongswan/wiki/Win7EapCert)

4. Edit /etc/ipsec.conf to be as follows: (source: https://wiki.strongswan.org/projects/strongswan/wiki/Win7EapMultipleConfig)

# ipsec.conf - strongSwan IPsec configuration file

config setup
    plutostart=no

conn %default
    keyexchange=ikev2
    ike=aes128-sha1-modp1024!
    esp=aes128-sha1!
    dpdaction=clear
    dpddelay=300s
    rekey=no

conn win7 
    left=%any
    leftsubnet=0.0.0.0/0
    leftauth=pubkey
    leftcert=vpnCert.pem
    leftid=@vpn.strongswan.org
    right=%any
    rightsourceip=10.10.3.0/24
    rightauth=eap-mschapv2
    #rightsendcert=never   # see note
    eap_identity=%any
    auto=add

5. Edit /etc/strongswan.conf to be as follows:
charon {
        dns1 = 8.8.8.8
        dns2 = 4.2.2.1
        load_modular = yes
        plugins {
                include strongswan.d/charon/*.conf
        }
}

6. Edit /etc/ipsec.secrets to be as follows (make sure there is a space between the name and the ":", otherwise strongswan won't recognize the name):

: RSA vpn.example.com.key.der

carol : EAP "abcd1234"
dave  : EAP "fghj5678"

7. ipsec start; and then use ipsec status/statusall to check status;
8. Change server ip_forward to 1; and add NAT rule: 
    sudo iptables -t nat -A POSTROUTING  -o eth0 -j MASQUERADE
9.Server configuration is complete. Follow this guide to configure your Windows 7 client: http://support.purevpn.com/how-to-setup-purevpn-manually-on-windows-7-ikev2  or this guide:   https://supportforums.cisco.com/document/98366/flexvpn-ikev2-windows-7-builtin-client-ios-headend-part-i-certificate-authentication




October 9, 2015

strongswan load test on ubuntu 14.04

Getting strongswan load test to run on 14.04.

Mostly from this post on the mailing list: https://lists.strongswan.org/pipermail/users/2011-August/001966.html

1. you will need to first access the following link

http://wiki.strongswan.org/projects/strongswan/repository/entry/src/libcharon/plugins/load_tester/load_tester_creds.c

and then 

- copy the RSA private-key into 2 files and name them "initiator_key.pem" 
and "responder_key.pem"

- copy the self-signed cert into 3 files and name 
them "cacert.pem", "initiator_cert.pem" and "responder_cert.pem"

On the Initiator GW/PC/Machine
--------------------------------
- Please note that the load-tester plugin can only act in and as a road-warrior-
client simulator mode. So you should be enabling the load-tester plugin on only 
the initiator linux-machine running the strongswan package

- The ipsec.conf file on this initiator is NEVER used or NOT required just 
comment out all config statments

- copy the cacert.pem, initiator_cert.pem and the initiator_key.pem to the 
respective locations "cacerts", "certs" and "private" under .../ipsec.d/ folder

- in the ipsec.secrets file, include the statement 
: RSA initiator_key.pem

- The strongswan.conf file should be as below:

------------------------------------------
charon {
    reuse_ikesa = no
    threads = 32

    plugins {
        load-tester {
            # enable the plugin
            enable = yes
            # example: 10 connections, 5 in parallel
            initiators = 5
            iterations = 2
            # use a delay of 100ms, overall time is: iterations * delay = 100s
            delay = 100
            # address of the gateway
            responder = 45.79.64.19
            load = yes
            # IKE-proposal to use
            proposal = aes128-sha1-modp2048
            # use faster PSK authentication instead of 1024bit RSA
            initiator_auth = pubkey
            responder_auth = pubkey
            # request a virtual IP using configuration payloads
            request_virtual_ip = yes
            # disable IKE_SA rekeying (default)
            ike_rekey = 0
            # enable CHILD_SA every 60s
            child_rekey = 60
            # do not delete the IKE_SA after it has been established (default)
            delete_after_established = no
            # do not shut down the daemon if all IKE_SAs established
            shutdown_when_complete = no
        }
    }
}
-----------------------------------------------------------

On the Responder GW/PC/Machine
******************************
- do not enable load-tester plugin here. just configure this machine as a Road-
Warrior-VPN-Server

- the ipsec.conf file should be as below:

# /etc/ipsec.conf - strongSwan IPsec configuration file

config setup

conn %default
        ikelifetime=60m
        keylife=30m
        rekeymargin=3m
        keyingtries=1
        keyexchange=ikev2
        mobike=no

conn rw-server
        left=%defaultroute
        leftcert=responder_cert.pem
        right=%any
        rightsourceip=10.3.0.0/16
        authby=pubkey
        keyexchange=ikev2
        type=tunnel
        auto=add

#

- copy the cacert.pem, responder_cert.pem and responder_key.pem to the 
respective locations under ipsec.d folder

- The ipsec.secrets file should have an entry as below:

: RSA responder_key.pem


2. That's it, now you start strongswan ipsec on both initiator and responder 
(first on this) using "ipsec start" or "ipsec start --nofork"

Use the following commands to examine the results:

ipsec status
ipsec statusall
ip route show route 220
ip -s xfrm state
ip -s xfrm policy

You may also want to know why if your strongswan is not logging at all:

http://tiebing.blogspot.com/2015/10/ubuntu-1404-strongswan-not-logging.html 

ubuntu 14.04 strongswan not logging

It turns out that ubuntu uses "AppArmor" to limit where strongswan can write files. You can install apparmor-utils and use the command "aa-complain" to turn strongswan binaries from "enforce" mode to "complain" mode:

# apt-get install apparmor-utils
# aa-status
# aa-complain /usr/lib/ipsec/charon
Setting /usr/lib/ipsec/charon to complain mode.

Just for reference,a strongswan conf file for logging:

charon {
    reuse_ikesa = no
        threads = 32

        load_modular = yes
        plugins {
                include strongswan.d/charon/*.conf
         }

       filelog {
               /var/log/charon.log {
                time_format = %b %e %T
                append = yes
                default = 1
               }
        }
}

This link is where I got the inspiration:
https://lists.strongswan.org/pipermail/users/2014-July/006351.html

October 6, 2015

openssl performance test

openssl speed -elapsed -multi 8 -evp aes-128-cbc

or aes-128-gcm

Forward traffic from one IP address to another

The first thing to do is do enable IP forwarding. This is done either by using:
 echo "1" > /proc/sys/net/ipv4/ip_forward
or
 sysctl net.ipv4.ip_forward=1

Then, we will add a rule telling to forward the traffic on port 1111 to ip 2.2.2.2 on port 1111:
 iptables -t nat -A PREROUTING -p tcp --dport 1111 -j DNAT --to-destination 2.2.2.2:1111

and finally, we ask Iptables to masquerade:

iptables -t nat -A POSTROUTING -j MASQUERADE

Disable “Waiting for network configuration” messages on Ubuntu boot

sudo vim /etc/init/failsafe.conf
I changed the first sleep command to
sleep 5
and then commented out the following lines:
$PLYMOUTH message --text="Waiting for network configuration..." || :
sleep 40
 
$PLYMOUTH message --text="Waiting up to 60 more seconds for network configuration..." || :
sleep 59
Just place a ‘#’ character at the beginning of each of those lines. Now it will just wait 5 seconds and then continue on.
To my surprise, the network was actually working just fine even though the script thinks it is not.

Just a note, do NOT remove the failsafe.conf file, otherwise it will hang the boot process indefinitely waiting for the network to be “configured.”

Windows netsh wlan command lines

To export a profile with password in clear, so that you can import it later:

netsh wlan export profile name="default2"  key=clear

list existing profiles: netsh wlan show profiles

  • To delete existing WLAN profile:  netsh wlan delete profile name=”profilename”
  • To Export WLAN profile to XML file: netsh wlan export profile name=”SSID”  This will export the WLAN configuration to .\ folder in XML format as Connection-SSID.XML
  • Import WLAN profile to the target computer: netsh wlan add profile filename=”c:\temp\filename.xml”  

netsh wlan show interfaces
netsh wlan show drivers
netsh wlan show networks
netsh wlan connect name="ProfileName"
netsh wlan disconnect
netsh wlan dump > myconfig.txt
netsh exec myconfig.txt

To make your wifi an access point:
netsh wlan set hostednetwork mode=allow ssid=SomeSSID key=passphrase
netsh wlan start hostednetwork

October 5, 2015

mysql logging

Running the following was the simplest way to dump queries to a log file without restarting
SET global log_output = 'FILE';
SET global general_log_file='/Applications/MAMP/logs/mysql_general.log';
SET global general_log = 1;
can be turned off with
SET global general_log = 0;

September 27, 2015

Linux VNC alternative: x2go

The ideal Linux terminal server has finally come true.
It is called X2Go, and it's open source and free. It's based on the NX protocol and works great, with Windows/Mac/Linux clients. 

September 26, 2015

use supervisor to monitor your process

https://serversforhackers.com/monitoring-processes-with-supervisord

sudo apt-get install -y supervisor

Let's create a configuration for it called webhooks.conf. This file will be created at /etc/supervisor/conf.d/webhooks.conf:
[program:nodehook]
command=/usr/bin/node /srv/http.js
directory=/srv
autostart=true
autorestart=true
startretries=3
stderr_logfile=/var/log/webhook/nodehook.err.log
stdout_logfile=/var/log/webhook/nodehook.out.log
user=www-data
environment=SECRET_PASSPHRASE='this is secret',SECRET_TWO='another secret'
Then:
supervisorctl reread
supervisorctl update

September 25, 2015

hg-git push: no changes found

If you use hg-git, and you know you have new changesets, but hg push is telling you "no changes found", using the following command may solve the problem:

hg bookmark -f master


This is because hg-git uses bookmark to simulate git branches. Somehow this bookmark wasn't moved with your latest hg update. So, this should fix it.

docker make file

build:
    docker build --rm -t logtest:v1 .
clean:
    @docker rm  `docker ps -a  | awk '/Exited/ || /Created/ {print  $$1}'`
    @docker rmi `docker images | awk '/^<none>/{print $$3}'`
list:
    docker ps -a
    echo
    docker images

Docker to find host IP address

netstat -nr | awk '/^0\.0\.0\.0/{print $2}'

September 17, 2015

join Linux to Windows domain

Use likewise-open

http://askubuntu.com/questions/452904/likewise-open-14-04-other-easy-way-to-connect-ad

http://www.powerbrokeropen.org/licensing/

 PowerBroker Identity Services – Open Edition git repository: git://source.pbis.beyondtrust.com/pbis.git

Windows Machine Authentication:
A few very helpful links to me:

http://ubuntuforums.org/archive/index.php/t-2141567.html
Many corporation deploy 802.1x machine authentication, because it's more secure than username authentication. Here's a guide of how to do such authentication.

The basic idea is that when a machine joins an AD domain, DC generates a password corresponding to that machine name. The password is transparent to administrators, but an open source software "likewise open" can get this password. So we can use machine name and password to do a 802.1x machine authentication, with PEAP-MSCHAPV2, other than EAP-TLS certificate.
https://learningnetwork.cisco.com/thread/33200?start=15&tstart=0

The client is configured to provide some form of credentials when it connects to an 802.1x network.  These credentials could be in the form of a username/password, machine account/password, certificate, or a number of other lesser used credentials.

The RADIUS server (ISE in your case), just needs to be able to verify if the supplied credentials are accurate.  To verify username/password credentials, it can look in the local user database, or reach out to external repositories, such as AD.  To verify machine account/password credentials, it will need to reach out to AD.  To verify certificates, it need to have the CA cert of the server that signed the client certificates installed.

In short, the client is the one that decides the credentials to supply, and ISE just needs to be able to validate them.

When discussing machone or user account authentication, you can do one or the other or even do both on a per client basis.

If you only want to do machine authentication, that's fine.  A benefit to machine authentication is that it can be done before a user actually logs into the PC.  So things like login scripts can be run.  But you can only do this on a PC that is in AD (unless you want to consider enabling EAP-TLS with certificates).

If you only want to do user authentication, that's fine as well.  This will happen after the user has logged into the OS.  So your laptop will not have a network connect if it's just sitting at a login prompt.

You can also do both.  Historically how this has worked is that the PC will do machine authentication when it first boots up.  Then once a user logs in, it will do a new authentication with the user credentials.  Not very many people did this.  With the latest anyconnect client and ISE, you can actually do both at the same time now (I think they call it EAP chaining).  But again, not many people do this.

September 16, 2015

Using netcat to send udp broadcast packet

1. You need to be root  on Linux
2. make sure you use the traditional netcat. In Ubuntu, that's nc.traditional
3. to send broadcast to broadcast address 192.168.1.255 port 8080, do this:

       echo -n "hello" | nc -b -u 192.168.1.255 8080 
4. OR, use ncat:

       echo -n "hello" | ncat -u 192.168.1.255 8080 

5. OR, use socat:
echo -n "hello" | socat - udp-datagram:192.168.1.255:8080,broadcast

August 31, 2015

Why do some WiFi routers block multicast packets going from wired to wireless

Source: http://superuser.com/questions/730288/why-do-some-wifi-routers-block-multicast-packets-going-from-wired-to-wireless
It's usually due to bugs in the Wi-Fi home gateway routers (APs), or sometimes in the wireless client chipsets/drivers/software.
On Wi-Fi, sending multicasts from the AP to the wireless clients (this is known in the standard as "From the Distribution System" or "FromDS") is tricky, so there are lots of ways it can fail, and it's easy to introduce bugs.
  1. Even though the radio medium is unreliable enough that 802.11 unicasts are required to have link-level acknowledgements (ACKs) and get retransmitted several times if there's no ACK, FromDS multicasts are never ACKed because they'd need to be ACKed by all the wireless clients of the AP, which could be quite an "ACK storm". So instead, FromDS multicasts have to be sent at a low data rate; using a simpler, slower, easy-to-decode-even-at-low-signal-to-noise-ratios modulation scheme, that can hopefully be received reliably by all the clients of the AP. Some APs let the administrator set the multicast rate, and some administrators unwittingly set it too high for some of their clients to receive reliably, breaking multicast delivery to those clients.
  2. When WPA (TKIP) or WPA2 (AES-CCMP) encryption is in use, FromDS multicasts have to be encrypted with a separate encryption key that is known to all of the clients (this is called the Group Key).
  3. When a client leaves the network, or every hour or so, just for good measure, the Group Key needs to be changed so that the client that left no longer has access to decrypt the multicasts. This "Group Key Rotation" process sometimes has problems. If a client doesn't acknowledge receipt of the new group key, the AP is supposed to de-authenticate that client, but if it fails to do that due to a bug, a client could have the wrong group key and thus be "deaf" to multicasts without realizing it.
  4. When WPA2 "mixed mode" is enabled (that is, when both WPA and WPA2 are enabled at the same time), the FromDS multicasts typically have to be encoded with the TKIP cipher, so that all clients are guaranteed to know how to decode it.
  5. FromDS multicasts have to be queued up by the AP and only transmitted at times when all clients who care about multicasts can be expected to have their receivers powered on. The time between the "safe to transmit FromDS multicasts" periods is called the "DTIM interval". If the AP or clients screw up their DTIM interval handling, it could result in clients unable to receive multicasts reliably.
  6. Some APs have features to keep wireless clients from being able to talk directly to each other, to maybe keep your wireless guests from hacking your other wireless guests. These features usually block multicasts from WLAN devices to other WLAN devices, and could well be implemented in a naive way that even blocks multicasts from LAN to WLAN.
The crazy thing is, "ToDS" multicasts are done just like ToDS unicasts, and so they rarely break. And since ToDS multicasts (not FromDS multicasts) are all that are needed when a wireless client gets a DHCP lease and ARPs to find its default gateway, most clients are able to get connected and surf the web, check email, etc. even when FromDS multicasts are broken. So a lot of people don't realize they have multicast problems on their network until they try to do things like mDNS (a.k.a. IETF ZeroConf, Apple Bonjour, Avahi, etc.).
A couple other things to note, regarding wired to wireless multicast transmissions:
  1. Most LAN multicasts, such as mDNS, are done using special multicast address ranges that are not meant to be routed across routers. Since Wi-Fi-capable home gateways with NAT enabled count as routers, mDNS is not meant to cross from WAN to [W]LAN. But it SHOULD work from LAN to WLAN.
  2. Because multicasts on Wi-Fi have to be sent at a low data rate, they take up a lot of airtime. So they're "expensive", and you don't want to have too many of them. That's the opposite of how things work on wired Ethernet, where multicasts are "less expensive" than sending separate unicasts to each machine "tuning into a multicast video stream" for example. Because of this, many Wi-Fi APs will do "IGMP Snooping" to watch which machines are sending Internet Group Management Protocol (IGMP) requests, expressing their desire to tune into a given multicast stream. Wi-Fi APs that do IGMP Snooping won't automatically forward some classes of multicasts onto the wireless network unless they see a wireless client try to subscribe to that stream via IGMP. The documents that describe how to do IGMP Snooping properly make it clear that certain classes of low-bandwidth multicasts (mDNS fits in this category) are supposed to always be forwarded even if no one has explicitly asked for them via IGMP. However, I wouldn't be surprised if there are broken IGMP Snooping implementations out there that absolutely never forward any kind of multicast until it sees an IGMP request for it.
tl;dr: Bugs. Lots of opportunities for bugs. And occasional poorly-designed features and configuration errors. Your best defense is to buy high-quality APs from companies that care about making sure multicasts work. Since Apple loves Bonjour (mDNS) so much, Apple's APs are probably the most consistently excellent at passing multicasts reliably, and Apple's Wi-Fi client devices are probably the most consistently excellent at receiving multicasts reliably.

August 13, 2015

how to start/stop and disable/enable a service in Ubuntu

http://askubuntu.com/questions/19320/how-to-enable-or-disable-services

Look at the 2nd answer.

Backup:

Currently there are actually 2 different ways for software to be started as a service in Ubuntu. A service is defined here as a program run by the system in the background, as opposed to one started and run directly by the user.
The traditional way to start services in Linux was to place a script in /etc/init.d, and then use the update-rc.d command (or in RedHat based distros, chkconfig) to enable/disable it. This command, btw, uses some mildly complicated logic to create symlinks in /etc/rc#.d, that control the order of starting services. If you run ls /etc/rc2.d you can see the order that services will be killed (K##xxxx) and started (S##xxxx).
The issue with that was that when booting the system, everything had to be done in serial, one thing after another, making system boot times really slow. Attempts were made to parallelize this, but they were haphazard and hard to take full advantage of. This was the main reason that Upstart was created.
Upstart uses job definition files in /etc/init to define on what events a service should be started. So, while the system is booting, upstart processes various events, and then can start multiple services in parallel. This allows them to fully utilize the resources of the system, for instance, by starting a disk-bound service up while another CPU-bound service runs, or while the network is waiting for a dynamic IP address to be assigned.
You can see all of the upstart job files by running ls /etc/init/*.conf
Let me just stop here and say that if you don't know what a service is, or what it does, DO NOT disable it!
Not all services have been converted to upstart. While working on the server team at Canonical for the past few months, I've worked on a number of converted job files, and the nicest part is that it allows one to get rid of all the script "magic" and just put in a few commands here and there to define exactly how to start the service, and nothing more. But for now, only a handful of traditional network services, like squid and samba, have been converted.
In order to figure out if a service is upstart based, you can run the status command:
status servicename
If its an upstart job, it will show this:
$ status statd
statd start/running, process 942
But if its not, you'll see something more like this:
$ status apache2
status: Unknown job: apache2
In this case, apache2 has not been converted to upstart. So, to disable apache2 you just run
sudo update-rc.d apache2 disable
sudo service apache2 stop
Upstart job definitions do not have an update-rc.d command. To disable the job, you need to edit the job file directly to disable it. There are two ways to do this.
If you want to still be able to manually start it, then you need to comment out the 'start on' condition. Say you want to install samba, but not have it start automatically.. here is its job file (in natty):
description "SMB/CIFS File Server"
author      "Steve Langasek <steve.langasek@ubuntu.com>"

start on local-filesystems
stop on runlevel [!2345]

respawn

pre-start script
    RUN_MODE="daemons"

    [ -r /etc/default/samba ] && . /etc/default/samba

    [ "$RUN_MODE" = inetd ] && { stop; exit 0; }

    install -o root -g root -m 755 -d /var/run/samba
end script

exec smbd -F
To disable it, you can just put a # in front of the 'start on local-filesystems'. Note that while it won't start back up on boot, you still need to stop it this time with
sudo service smbd stop
If, however, you never want it to start, I'd suggest actually removing the package. If, however, you want it installed, but not startable, you can also do:
mv /etc/init/smbd.conf /etc/init/smbd.conf.disabled
Starting with the version of upstart that will be in 11.04, there is a new keyword that disables the 'start on' and 'stop on' stanzas, it is 'manual'. So another way to disable the service as of 11.04 is to do:
command using sudo
echo 'manual' | sudo tee /etc/init/mysql.override

command from root shell
echo manual >> /etc/init/mysql.override
And, hopefully real soon, you will be able to create an "override" file to disable a service without editing the job definition at all, by just putting the 'manual' keyword in it.

July 16, 2015

gvim display GB2312 chinese

set guifont=NSimSun:h12:cGB2312

July 11, 2015

Simple Golang Example of os.exec on Windows

package main

import (
"fmt"
"log"
"os/exec"
"strings"
)

func doCmd(cmd string) string {
parts := strings.Fields(cmd)
head := parts[0]
parts = parts[1:len(parts)]
out, err := exec.Command(head, parts...).Output()
if err != nil {
log.Fatal(err)
}
return string(out)
}

func main() {
cmd := "netsh wlan show networks mode=bssid"
out := doCmd(cmd)
fmt.Printf("%s\n", out)
}

Windows 7 WiFi scripting

To display all wireless interfaces:
netsh wlan show interfaces
To show the wireless drivers installed run this command. This is particularly interesting as exploits in drivers do exist and most admins do not pay as close attention to driver versions as other types of software:
netsh wlan show drivers
To list available wireless networks (similar to Linux’s iwlist scan option)
netsh wlan show networks
or 
netsh wlan show networks mode=bssid (this shows more BSSID and signal strength)
To view profiles of networks saved on this machine:
netsh wlan show profiles
To make Windows connect to the specified profile (usually named after the SSID of the network):
netsh wlan connect name="ProfileName"
To export the profile details to an XML file (which includes an encrypted version of the PSK if applicable):
netsh wlan export profile name="ProfileName"

To delete a profile
netsh wlan delete profile name="ProfileName"

To Add a profile
netsh wlan add profile filename=c:\temp\myprofile.xml

XML for a WPA2-PSK Wifi networks looks like this


<?xml version="1.0"?>
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
<name>YOUR_NETWORK_NAME</name>
<SSIDConfig>
<SSID>
<hex>HEX-of-your-network-name, for example, "abc" would be "616263"</hex>
<name>YOUR_NETWORK_NAME</name>
</SSID>
</SSIDConfig>
<connectionType>ESS</connectionType>
<connectionMode>auto</connectionMode>
<MSM>
<security>
<authEncryption>
<authentication>WPA2PSK</authentication>
<encryption>AES</encryption>
<useOneX>false</useOneX>
</authEncryption>
<sharedKey>
<keyType>passPhrase</keyType>
<protected>false</protected>
<keyMaterial>YOUR-NETWORK-PASSOWRD</keyMaterial>
</sharedKey>
</security>
</MSM>
</WLANProfile>



Now crucially, here are the commands to turn the Windows 7 (or Server 2008 R2) into an Access Point sharing its existing wireless connection out to others:
netsh wlan set hostednetwork mode=allow ssid=SomeSSID key=passphrase
The hosted network is now created but it is not yet started. To start it, issue the command:
netsh wlan start hostednetwork
Your Windows box is now advertising a network “SomeSSID” (in this case) which other machines can connect to. No notification is given on the Windows box that this has happened and no further notification happens when someone connects.

Vivek stated Microsoft’s response was it wasn’t being exploited “in the wild” therefore nothing would be done about it. Happy WiFi backdooring. :-)

A simple C++ logger class

log.h

#ifndef __LOG1_H__

#define __LOG1_H__

#include <sstream>
#include <string>
#include <stdio.h>

class Log
{
public:
    Log(){};
    ~Log();
    std::ostringstream& Get();
protected:
    std::ostringstream os;
};

inline Log::~Log()
{
    os << std::endl;
    fprintf(stderr, "%s", os.str().c_str());
    fflush(stderr);
}

inline std::ostringstream& Log::Get()
{
    os << " " <<  ": ";
    return os;
}

#define log() Log().Get()

#endif //__LOG_H__


test.cpp:
log() << "A loop with " << count << " iterations";

June 23, 2015

linux process with a lot of open sockets

etc/sysctl.conf file:


# General gigabit tuning:
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_syncookies = 1
# this gives the kernel more memory for tcp
# which you need with many (100k+) open socket connections
net.ipv4.tcp_mem = 50576   64768   98152
net.core.netdev_max_backlog = 2500

then run as root: sysctl -p

Then:

sudo bash
ulimit -n 999999
./your-program

June 18, 2015

May 27, 2015

ath9k create multiple interfaces

  • To create/delete virtual interfaces:
    iw dev wlan0 interface add [virtual-sta-name] type station
    iw dev wlan0 interface add [virtual-ap-name] type __ap
    ip link set [interface-name] address [unique-mac-addr]
  • To delete virtual interface:
    iw dev [dev-name] del
  • use iw to check wlan device status

    $ cat /proc/net/wireless 
    Inter-| sta-|   Quality        |   Discarded packets               | Missed | WE
     face | tus | link level noise |  nwid  crypt   frag  retry   misc | beacon | 22
     wlan0: 0000   56.  -54.  -256        0      0      0      0      0        0
    
    
    
    
    OR
    
    
    $ iw dev wlan0 link
    Connected to 00:10:7A:93:AE:BF (on wlan0)
        SSID: SECRETSSID
        freq: 2462
        RX: 89045514 bytes (194863 packets)
        TX: 34783321 bytes (164504 packets)
        signal: -54 dBm
        tx bitrate: 48.0 MBit/s

    May 26, 2015

    openwrt unbind led gpios

    # Turn off the LEDs
    root@OpenWrt:/# echo "leds-gpio" > /sys/bus/platform/drivers/leds-gpio/unbind
    root@OpenWrt:/# cat /sys/kernel/debug/gpio
    GPIOs 0-21, ar2315-gpio:
    gpio-0   (sysfs               ) in  lo
    gpio-5   (reset               ) in  hi
    gpio-6   (sysfs               ) in  lo

    Now you can use gpio export (i.e echo 11 > /sys/class/gpio/export), and change 'direction' and 'value'  of the gpio to directly control it.

    use time to test multiple commans

    /usr/bin/time /bin/sh -c 'ls;pwd;ls'

    May 20, 2015

    cross compile openJDK for ARM

    Source: http://mail.openjdk.java.net/pipermail/zero-dev/2014-December/000538.html

    when I cross-compile OpenJDK 9 for ARM32 I pass the following configure 
    options
    
    configure
    # these options tell openjdk to do a cross compile build.
    --build=x86_64-unknown-linux-gnu
    --host=arm-buildroot-linux-gnueabi
    --target=arm-buildroot-linux-gnueabi
    
    # these two options enable zero
    --with-jvm-interpreter=cpp
    --with-jvm-variants=zero
    
    # specific options to make the build find the X and freetype headers and 
    librarys found on the ARM32 root filesystem.
    --disable-freetype-bundling
    --with-freetype-include=/home/xranby/rpi-buildroot/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/usr/include/freetype2
    --with-freetype-lib=/home/xranby/rpi-buildroot/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/usr/lib
    --with-freetype=/home/xranby/rpi-buildroot/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/usr/
    --with-x=/home/xranby/rpi-buildroot/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/usr/include
    
    # the sysroot shall point to the ARM32 root file system, the build will 
    use librarys inside the sys root during linking native libraries.
    --with-sys-root=/home/xranby/rpi-buildroot/output/host/usr/arm-buildroot-linux-gnueabi/sysroot
    # The tools dir contains binarys to run on the host x86 system, you may 
    point this to your system root dir /
    # in my case the tools i use have been compiled by buildroot thus I use 
    the buildroot tools dir.
    --with-tools-dir=/home/xranby/rpi-buildroot/output/host
    # OpenJDK 9 require OpenJDK 8, i point with boot jdk to an OpenJDK 8 
    image that can be run on the host x86 system.
    --with-boot-jdk=/home/xranby/images-jdk8/j2sdk-image/
    
    # some parts of the openjdk build still expect that the cross compile 
    tools are found in the system PATH
    # on my system i have to explicitly tell where the tools are located 
    because my cross compile toolchain is not found on the path.
    # i use gcc to do the linking instead of ld because the openjdk build 
    passes -Xlinker -z
    OBJCOPY=/home/xranby/rpi-buildroot/output/host/usr/bin/arm-buildroot-linux-gnueabi-objcopy
    STRIP=/home/xranby/rpi-buildroot/output/host/usr/bin/arm-buildroot-linux-gnueabi-strip
    CPP=/home/xranby/rpi-buildroot/output/host/usr/bin/arm-buildroot-linux-gnueabi-cpp
    CXX=/home/xranby/rpi-buildroot/output/host/usr/bin/arm-buildroot-linux-gnueabi-g++
    CC=/home/xranby/rpi-buildroot/output/host/usr/bin/arm-buildroot-linux-gnueabi-gcc
    LD=/home/xranby/rpi-buildroot/output/host/usr/bin/arm-buildroot-linux-gnueabi-gcc
    CPP_FLAGS=-lstdc++
    CXX_FLAGS=-lstdc++
    
    
    when running make i pass the following options to make
    # BUILD_CC and BUILD_LD shall point to host x86 executables.
    BUILD_CC=gcc
    BUILD_LD=gcc
    OBJCOPY=/home/xranby/rpi-buildroot/output/host/usr/bin/arm-buildroot-linux-gnueabi-objcopy
    STRIP=/home/xranby/rpi-buildroot/output/host/usr/bin/arm-buildroot-linux-gnueabi-strip
    CPP=/home/xranby/rpi-buildroot/output/host/usr/bin/arm-buildroot-linux-gnueabi-cpp
    CXX=/home/xranby/rpi-buildroot/output/host/usr/bin/arm-buildroot-linux-gnueabi-g++
    CC=/home/xranby/rpi-buildroot/output/host/usr/bin/arm-buildroot-linux-gnueabi-gcc
    LD=/home/xranby/rpi-buildroot/output/host/usr/bin/arm-buildroot-linux-gnueabi-gcc
    #and finally the target, this will build compact profiles, jre and jdk 
    images.
    all images profiles CONF=linux-arm-normal-zero-release
    
    
    I have automated these configure and make options for openjdk 9 into 
    buildroot build scripts
    https://github.com/xranby/rpi-buildroot/tree/openjdk
    
    >
    > I've done Zero builds before but have never used OpenJDK's cross-compile
    > feature to build it on ARMv7. There is an Arm32 bit JIT in IcedTea[1],
    > but I don't know if that can be cross-compiled.
    
    If you cross compile icedtea then you need to make sure that the 
    bytecode generator tool is compiled by the host x86 toolchain.
    openembedded meta-java contains buildscripts that can cross compile the 
    Arm32 JIT found in IcedTea.
    https://github.com/woglinde/meta-java
    
    Cheers
    Xerxes

    May 6, 2015

    hg change history

    hg rebase, hg histedit, hg graft, hg strip, hg strip --keep, and hg commit --amend.

    April 30, 2015

    vim ctags tags path

    This line in your ~/.vimrc should help:
    set tags=./tags,tags;$HOME
    

    It tells Vim to look for a tags file in the directory of the current file, in the current directory and up and up until your $HOME (that's the meaning of the semicolon), stopping on the first hit.

    April 27, 2015

    golang win32 UI

    https://github.com/lxn/walk

    OR

    https://github.com/AllenDang/gform

    OR

    https://github.com/andlabs/ui

    April 23, 2015

    USB terms

    In the USB world, the most basic data transfer is done in packet, but to understand the on-the-wire protocol, there are other things to understand.

    Packet
    USB Packet types: (Source: http://www.usbmadesimple.co.uk/ums_3.htm)

    PID Type PID Name PID<3:0>*
    Token OUT 0001b
    IN 1001b
    SOF 0101b
    SETUP 1101b
    Data DATA0 0011b
    DATA1 1011b
    DATA2 0111b
    MDATA 1111b
    Handshake ACK 0010b
    NAK 1010b
    STALL 1110b
    NYET 0110b
    Special PRE 1100b
    ERR 1100b
    SPLIT 1000b
    PING 0100b
    Reserved 0000b

    Transaction: 
       
    One transaction has 3 packets: Token + Data + Handshake for a successful transaction. (*). Nak and Stall error condition could happen after Token when no data is available.

    There are 3 types of transactions: IN, OUT, SETUP

     *: For IN and OUT transactions used for isochronous transfers, there are only 2 packets; there is no handshake packet.

    Transfer:
    There are 4 types of transfer:

    • Control 
    • Interrupt
    • Bulk
    • Isochronous (such as audio data)
    HID device only uses Control and Interrupt

    Control transfer = 3 transactions: SETUP + IN/OUT DATA + STATUS(IN/OUT transaction)
    Other transfers has just one transaction: IN/OUT data.

    In general, you want to pay attention to Transfer or Transaction level, not packet level. 

    April 22, 2015

    prevent ssh client timeout

    Add this in /etc/ssh/ssh_config for Linux and ~/.ssh/config for Mac:

    
    
    Host *
    ServerAliveInterval 120
    

    linux cp without overwrite

    You can use "-n" option.

    If you are on a embedded linux box with busybox, it does not have that option. You can this instead:

    false | cp -i source destination 2>/dev/null

    April 16, 2015

    Vim show C function name

    Put this in your .vimrc file, and use key "f" to show current function name:

    fun! ShowFuncName()
      let lnum = line(".")
      let col = col(".")
      echohl ModeMsg
      echo getline(search("^[^ \t#/]\\{2}.*[^:]\s*$", 'bW'))
      echohl None
      call search("\\%" . lnum . "l" . "\\%" . col . "c")
    endfun
    map f :call ShowFuncName() <CR>

    April 15, 2015

    golang combine static data (css/js/images/) with binary file

    https://github.com/tiebingzhang/statik (zip the contents and compiled it into go source code, very small code base, this is a github fork with the slash fix)

    https://github.com/jteeuwen/go-bindata

    https://github.com/GeertJohan/go.rice (can either compile zip into go source, or append the zip to existing go EXE, more flexible but code base is a little larger)

    April 14, 2015

    script to detected unused C files

    If you have a large project with a lot of C files, once you compiled them, you will end up with a lot of .o files. Then you can use the .o files to find out which .c files is not used (conditionally compiled/not compiled). To do this, follow the steps below:

    1. cd subdir
    2. ls -1 > ../1.out
    3. gawk -f lsnu.awk ../1.out

    The lsnu.awk script
    {
            if ($1 ~ /\.c$/){
                    cfiles[$1]=1;
                    print $1;
                    next;
            }
            if ($1 ~ /\.o$/){
                    ofiles[$1]=1;
                    #printf("%s\n",$1);
                    next;
            }

    }

    END{
            printf("-------------\n");
            for ( i in  cfiles){
                    f=i;
                    gsub(/\.c$/,".o",i);
                    if (ofiles[i]!=1){
                            printf("%s ",f);
                            }
            }
            printf("\n");
    }

    March 12, 2015

    cmake add include path and library path

    Some tips for cMake beginners. This is done on Linux.

    How to use cMake

    cmake generates a bunch of intermediate files, including the final Makefile. To make things clean, make a separate directory for the build process:

    mkdir build
    cd build
    cmake ..

    To re-run cmake after changing the CMakeLists.txt, do:

    cd build
    rm -rf *
    cmake ..

    Cross Compile to ARM

    To cross compile to an embedded target, add the following lines to you CMakeLists.txt at the very top (after VERSION)
    SET(CMAKE_SYSTEM_NAME Linux)
    SET(CMAKE_C_COMPILER arm-none-linux-gnueabi-gcc)

    Add include paths

    include_directories("${PROJECT_SOURCE_DIR}/../" "${PROJECT_SOURCE_DIR}/build/" "${PROJECT_SOURCE_DIR}")

    Add a library

    FIND_LIBRARY(json json-c json)

    1st parameter: output,  The variable that will hold the results of FIND_LIBRARY
    2nd parameter: the library to look for (in this case, libjson-c.so)
    3rd parameter: the path to look, starting with ${PROJECT_SOURCE_DIR}

    The returned varilable can be used in the following statement to add the library to link time:
    TARGET_LINK_LIBRARIES(${json})

    Assign a variable

    SET(LIBS ${ubox} ${blobmsg_json} ${json})

    assigns the concatenated value of ubox, blobmsg_json and json to the variable LIBS



    March 11, 2015

    AT&T Data plan web page

    https://buyasession.att.com

    Linux running 4G LTE modem

    The modem I have is Sierra Wireless Air Prime MC7453 Mini PCI Express Module.  The carrier I tested is AT&T.

    Before running on Linux, I had to install the card on a regular Laptop that supports 4G card, and run Windows 7 on the laptop, install all the drivers and the Sierra Wireless Connect Manager to try out the card. This confirmed that the card has the latest firmware, and the carrier setting is correct, etc.

    Next I run it on Linux. Instead of using the Gobi driver from Sierra Wireless, I used the qmi_wwan driver in the latest Linux (after kernel version 3.14).  An user land utility is also needed. libqmi seems to be popular, but it depends on a fairly new version of glib, which itself depends on a bunch of libraries. It becomes a hassle to compile everything. Then I discovered uqmi, a small utility developed and used by the openwrt project. It's much more lightweight, and seems to be pretty mature. I was able to get my modem to connect and ping with the following commands.

    device="/dev/cdc-wdm1"
    modes="lte"
    uqmi -s -d "$device" --get-pin-status
    uqmi -s -d "$device" --get-serving-system
    uqmi -s -d "$device" --set-data-format 802.3
    uqmi -s -d "$device" --wda-set-data-format 802.3
    uqmi -s -d "$device" --set-network-modes "$modes"
    wds=`uqmi -s -d "$device" --get-client-id wds`
    uqmi -s -d "$device" --set-client-id wds,"$wds" --start-network "ISP.CINGULAR" --autoconnect
    uqmi -s -d "$device" --get-signal-info
    uqmi -s -d "$device" --get-data-status
    dhclient wwan1

    Now I can ping

    To disconnect:
    uqmi -s -d "$device" --stop-network 0xffffffff    --autoconnect > /dev/null


    [1] The home page of uqmi:  http://nbd.name/gitweb.cgi?p=uqmi.git;a=summary
    [2] A list of useful commands of how to use uqmi: http://trac.gateworks.com/wiki/modem
    [3] The official Openwrt qmi script that uses uqmi:  https://dev.openwrt.org/browser/trunk/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh
    [4] Another useful link: https://lists.openwrt.org/pipermail/openwrt-devel/2014-April/025046.html

    March 5, 2015

    How to get Linux USB Report Descriptor when it says UNAVAILABLE

    Start by plugging in your USB device and running dmesg to get the kernel output for the event. It will look something like this:

    input: Sony PLAYSTATION(R)3 Controller as /devices/pci0000:00/0000:00:04.1/usb2/2-4/2-4.2/2-4.2:1.0/input/input16
    
    
    
    The first line input: ... is what we want. It contains the full device path and in this case we are interested in third last component of the path: 2-4.2:1.0.

    To get the USB report Descriptor with "lsusb -v", we need to unbind the device first (as root).
    $ sudo bash -c "echo -n 2-4.2:1.0 >/sys/bus/usb/drivers/usbhid/unbind"
    

    Now run lsusb again for the device and you should see the report descriptor in the output!

    Patch Linux kernel to support Esterline Medigenic keyboard

    The Esterline Medigenic keyboard does not work under stock Linux kernel (as of kernel version 4.0RC). This is because the HID Report Descriptor of the keyboard is wrong for Linux (and Mac OS). Under Linux kernel tree driver/hid there are a bunch of "special" drivers for different hid devices, and we can create one for the medigenic keyboard to fix up the HID report descriptor so that it works under Linux.

    1. Create a file under driver/hid called hid-medigenic.c with the following content:
    /*
     * This program is free software; you can redistribute it and/or modify it
     * under the terms of the GNU General Public License as published by the Free
     * Software Foundation; either version 2 of the License, or (at your option)
     * any later version.
     */

    #include <linux/device.h>
    #include <linux/hid.h>
    #include <linux/module.h>

    #include "hid-ids.h"

    /* the fixups that need to be done:
     *   - change keyboard Usage Mininum from 1 to 0
     */
    static __u8 *medigenic_report_fixup(struct hid_device *hdev, __u8 *rdesc,
                    unsigned int *rsize)
    {
            if (*rsize >= 59 &&
                    rdesc[24] == 0x19 && rdesc[25] == 0x01 &&
                    rdesc[26] == 0x29 && rdesc[27] == 0x65 ) {
                    dev_info(&hdev->dev, "fixing up medigenic keyboard report descriptor\n");
                    rdesc[25] = 0x00;
            }
            return rdesc;
    }

    static const struct hid_device_id medigenic_devices[] = {
            { HID_USB_DEVICE(USB_VENDOR_ID_ESTERLINE, USB_DEVICE_ID_MEDIGENIC) },
            { }
    };
    MODULE_DEVICE_TABLE(hid, medigenic_devices);

    static struct hid_driver medigenic_driver = {
            .name = "medigenic",
            .id_table = medigenic_devices,
            .report_fixup = medigenic_report_fixup,
    };

    static int __init medigenic_init(void)
    {
            return hid_register_driver(&medigenic_driver);
    }

    static void __exit medigenic_exit(void)
    {
            hid_unregister_driver(&medigenic_driver);
    }

    module_init(medigenic_init);
    module_exit(medigenic_exit);
    MODULE_LICENSE("GPL");

    2. Edit file driver/hid/hid-ids.h to add the following two lines:
    #define USB_VENDOR_ID_ESTERLINE 0x059d
    #define USB_DEVICE_ID_MEDIGENIC 0x0708


    3. Edit file driver/hid/Kconfig to add the following lines:
    config HID_MEDIGENIC
        tristate "Medigenic Keyboard Support" if EMBEDDED
        depends on USB_HID
        default !EMBEDDED
        ---help---
        Support for Medigenic keyboard.

    4. Edit file driver/hid/Makefile to add the following line:
    obj-$(CONFIG_HID_MEDIGENIC)     += hid-medigenic.o

    Then in top directory of kernel, do make menuconfig, and exit, and save (somehow medigenic is automatically set to Y when you do this). Check .config to make sure you have the following line:
    CONFIG_HID_MEDIGENIC=y

    The build your kernel and the keyboard should work now.

    memdump function in kernel

    void memdump(unsigned char *rdesc, int *rsize){
        int i,pos=0;
        unsigned char outbuf[256];
        printk(KERN_WARNING "rsize=%d\n",*rsize);
        for (i=0;i<*rsize;i++){
            pos+=sprintf(outbuf+pos,"%02x ",rdesc[i]);
            if (i>0 && ((i+1)%16)==0){
                printk(KERN_WARNING "%04x dump %s\n",(i/16)*16,outbuf);
                pos=0;
            }
        }
        if (pos>0){
            printk(KERN_WARNING "%04x dump %s\n",(i/16)*16,outbuf);
        }
    }

    March 3, 2015

    replace systemd with a simple busybox inittab

    1. install busybox
    2. create file /etc/inittab with the following content:
    # Start "rc init" on boot
    ::sysinit:/opt/rc init

    # Set up the TTY's 1 through 4
    tty1::askfirst:/sbin/agetty -8 -s 38400 tty1 linux
    tty2::respawn:/sbin/agetty -8 -s 38400 tty2 linux

    # Stop all services on shutdown
    ::shutdown:/opt/rc shutdown

    # Killing everything on shutdown
    ::shutdown:echo :: sending SIGTERM to all
    ::shutdown:/bin/kill -s TERM -1
    ::shutdown:sleep 1
    ::shutdown:echo :: sending SIGKILL to all
    ::shutdown:/bin/kill -s KILL -1

    # Unmount everything on shutdown
    ::shutdown:echo :: unmounting everything
    ::shutdown:/bin/umount -a -r
    ::shutdown:/bin/mount -o remount,ro /

    3. ln -s /bin/busybox /opt/init
    4. create /opt/rc with the following content:
    #!/bin/sh
    on_boot() {
        #===================
        # mount the API filesystem
        # /proc, /sys, /run, /dev, /run/lock, /dev/pts, /dev/shm
        echo 3 mounting API filesystem...
        mountpoint -q /proc    || mount -t proc proc /proc -o nosuid,noexec,nodev
        mountpoint -q /sys     || mount -t sysfs sys /sys -o nosuid,noexec,nodev
        mountpoint -q /run     || mount -t tmpfs run /run -o mode=0755,nosuid,nodev
        mountpoint -q /dev     || mount -t devtmpfs dev /dev -o mode=0755,nosuid
        mkdir -p /dev/pts /dev/shm
        mountpoint -q /dev/pts || mount -t devpts devpts /dev/pts -o mode=0620,gid=5,nosuid,noexec
        mountpoint -q /dev/shm || mount -t tmpfs shm /dev/shm -o mode=1777,nosuid,nodev

        #===================
        # initialize system
        echo 3 setting up loopback device...
        /usr/sbin/ip link set up dev lo

        echo 3 initializing udev...
            busybox mdev -s
            echo /sbin/mdev > /proc/sys/kernel/hotplug

        echo 3 setting hostname...
        cat /etc/hostname >| /proc/sys/kernel/hostname

        echo 3 mounting...
        mount -a
        mount -o remount,rw /

            dhclient eth0&
            /etc/init.d/ssh start&
    }

    on_shutdown() {
        #===================
        echo 3 shutting down udev...
            killall busybox
            killall mdev

        #===================
        # umount the API filesystem
        echo 3 unmounting API filesystem...
        umount -r /run
    }

    #===================
    # handle arguments
    case "$1" in
    init)
        on_boot;;
    shutdown)
        on_shutdown;;
    esac

    5. reboot and add the following parameter to your kernel command line on grub:
    init=/opt/init

    Enjoy