Jumat, 23 Desember 2011

VirtualBox with Scientific Linux 6.1 using Intel Pentium IV without hardware virtualization

I recently got an old PC to play with as testing machine and planning to use this machine to show a proof of concept about VDI to my coworkers. The machine is an old 2.4 GHz Pentium IV. Without any recent hardware virtualization extension my choice is limited to type 2 virtualization software.
I settle with VirtualBox and installed version 4.1 from Oracle repository
Installation procedure:

  1. Make sure we have the dependencies installed which is kernel-devel, gcc and make
    # yum install kernel-devel gcc make
  2. Create virtualbox repo in /etc/yum.repos.d/
    # vi /etc/yum.repos.d/virtualbox.repo
    [virtualbox]name=RHEL/CentOS/ScientificLinux-$releasever / $basearch - VirtualBox baseurl=http://download.virtualbox.org/virtualbox/rpm/rhel/6Server/$basearchenabled=1gpgcheck=1gpgkey=http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc
  3. Notice that we have hardcoded the path of baseurl to 6Server, because i can not find 6.1 branch yet from http://download.virtualbox.org/virtualbox/rpm/rhel. In case this situation changes in the future we can use the stock virtualbox.repo from Oracle
  4. Install VirtualBox # yum install VirtualBox-4.1
  5. Installation will take a couple of minutes, because during installation a new kernel module will be compiled from source. Any error can be examined from /var/log/virtualbox.log. VirtualBox also depends on quite some packages amounting to 96M download
I planned to do vboxheadless, so i do not install any X Window or Desktop package, since this is a testing machine i do not want to play with firewall headache so turn off firewall and SELinux. I'll cover the firewall rules later :).
# vi /etc/selinux/config
SELINUX=permissive
# system-config-firewall-tui

Turn off Firewall


To control this machine, we will install phpVirtualBox
  1. Create /etc/default/virtualbox
    # vi /etc/default/virtualbox
    VBOXWEB_USER=vbox
    VBOXWEB_HOST=<ip>
    VBOXWEB_PORT=18083
    VBOXWEB_LOGFILE=/var/log/virtualbox/vboxweb
    INSTALL_DIR=/usr/lib/virtualbox
  2. Create user vbox with primary group vboxusers (created during VirtualBox installation)
    # useradd vbox -g vboxusers
    # passwd vbox
  3. Create log directory
    # mkdir /var/log/virtualbox
    # chgrp vboxusers /var/log/virtualbox
    # chmod g+rwx /var/log/virtualbox
  4. Activate vboxweb-service
    # service vboxweb-service start
    # chkconfig vboxweb-service on
  5. Download the latest phpVirtualBox from http://code.google.com/p/phpvirtualbox/downloads/list
  6. Install php-soap (phpVirtualBox requirement)
    # yum install php-soap
  7. Extract the latest phpVirtualBox to /var/www/html/phpVirtualBox
  8. Edit config.php, with the most important settings
    var $username = vbox
    var $password = <the password that is set before>
    var $location = http://<vbox_server_ip>:18083/
  9. Point your browser to http://<vbox_server_ip>/phpVirtualBox
  10. Login with username admin, password admin. Change the password immediately
  11. Voila! We are ready to virtualize
Update: 20120109
To install OS to the VMs, we will need to install VirtualBox Extpack, so we can have Remote Display
  1. Download the corresponding extension pack from virtualbox website. As of this article, it is Oracle_VM_VirtualBox_Extension_Pack-4.1.8-75467.vbox-extpack
  2. Install
    # vboxmanage extpack install Oracle_VM_VirtualBox_Extension_Pack-4.1.8-75467.vbox-extpack
  3. In the VM definition, activate Remote Display and give Video Memory at least 4 MB (otherwise your virtual OS will crashed with GuestAddition). We can use any high numbered ports as long the ports are not locked by other process.
  4. Since VirtualBox OSE do not include absolute pointing device, mouse movement will be difficult during OS installation, but after your VM OS installed, the GuestAddition will correct that
With Windows 2003 VM, we can have problem with Ctrl-Alt-Del in Remote Display. In that case use the console feature of phpVirtualBox.


OpenSSL CA HowTo with Scientific Linux 6.1

This is a reminder for me about how to set up 2 steps CA using OpenSSL in Scientific Linux 6.1 (should also apply to CentOS)
Most OpenSSL HowTo (that I can find using google) is quite old, although the concepts are still the same
My Requirements:
  1. 2 Steps CA ie: ROOT CA and Intermediate CA
  2. ROOT CA is valid for 10 years, Intermediate CA is valid for 3 years. All other Certificate is valid for 1 year
  3. All private keys are 8192 bits long and protected with random pass phrase up to 30 characters long
  4. All certificates will have Key Usage field defined to minimize misuse
  5. Certificate Digest using sha512, since sha1 is considered broken by now. OpenSSL 1.0 support sha512. To verify what digest method available run
    # openssl dgst -h
  6. Root CA and Intermediate CA will be exported in format suitable for Mozilla and Windows
OpenSSL1.0 is installed with base system. The structure for CA is located in /etc/pki/CA with system wide openssl.cnf located in /etc/pki/tls/openssl.cnf
We will make copy of /etc/pki/CA to /etc/pki/rootCA as our Root CA directory, then we will link required files to /etc/pki/CA
  • # cp -r /etc/pki/CA /etc/pki/rootCA
First we make some changes to the stock openssl.cnf to better reflect our organization
  • # cp /etc/pki/tls/openssl.cnf /etc/pki/rootCA/rootca.cnf
  • # vi /etc/pki/rootCA/rootca.cnf
    Changes in section [ CA_default ]
    dir = /etc/pki/rootCA
    certificate = $dir/rootcacert.pem
    private_key = $dir/private/rootcakey.pem
    crl = $dir/rootcrl.pem
    default_days = 1096
    default_md = sha512
    Changes in section [ req ]
    default_bits = 8192
    default_md = sha512
    req_extensions = v3_req
    Changes in [ req_distinguished_name ]
    as needed
    add commonName_default = some name
    Changes in [ usr_cert ]
    basicConstraints=CA:TRUE, pathlen:0
    keyUsage = critical, cRLSign, keyCertSign
    crlDistributionPoints = URI:http:///your-webserver/rootca.crl
    Changes in [ v3_req ]
    basicConstraints = CA:TRUE, pathlen:0
    keyUsage = critical, cRLSign, keyCertSign
    Changes in [ v3_ca ]
    keyUsage = critical, cRLSign, keyCertSign
To create ROOT CA private key
  • # openssl genrsa -des3 -out /etc/pki/rootCA/private/rootcakey.pem 8192
    When prompted for password, generate strong password (www.strongpasswordgenerator.com). Remember to document it somewhere safe (physically)
  • Secure it using mode 400
    # chmod 400 /etc/pki/rootCA/private/rootcakey.pem
To create self signed ROOT CA Certificate
  • # openssl req -new -x509 -days 3653 -key /etc/pki/rootCA/private/rootcakey.pem -out /etc/pki/rootCA/rootcacert.pem -config /etc/pki/rootCA/rootca.cnf
  • Secure it
    #  chmod 400 /etc/pki/rootCA/rootcacert.pem
  • Verify it
    # openssl x509 -noout -text -in /etc/pki/rootCA/rootcacert.pem
    Should have
    X509v3 Basic Constraints:
      CA:TRUE
    X509v3 Key Usage: critical
      Certificate Sign, CRL Sign
Prepare ROOT CA directories and files
  • # touch /etc/pki/rootCA/index.txt
  • # echo '01' > /etc/pki/rootCA/serial
  • # echo '01' > /etc/pki/rootCA/crlnumber
Next we need to create our Intermediate CA-1
  • # cp -r /etc/pki/CA /etc/pki/CA1
Next we need to create Intermediate CA1 private key like above, just alter the file name

  • # openssl genrsa -des3 -out /etc/pki/CA1/private/cakey.pem 8192
    When prompted for password, generate strong password (www.strongpasswordgenerator.com). Remember to document it somewhere safe (physically)
  • Secure it using mode 400
    # chmod 400 /etc/pki/CA1/private/cakey.pem

Next Create Certificate Request for CA1

  • # openssl req -new -key /etc/pki/CA1/private/cakey.pem -out /etc/pki/rootCA/request/ca1cert.req -config /etc/pki/rootCA/rootca.cnf
  • Verify it
    # openssl req -in /etc/pki/rootCA/request/ca1cert.req  -noout -text
    Should have this section
    Requested Extensions:
      X509v3 Basic Constraints:
        CA:TRUE, pathlen:0
      X509v3 Key Usage: critical
        Certificate Sign, CRL Sign
Then we sign it using Root CA
  • # openssl ca -config /etc/pki/rootCA/rootca.cnf -infiles /etc/pki/rootCA/request/ca1cert.req
  • The copy of CA1 certificate will be placed at /etc/pki/rootCA/newcerts/01.pem
  • Move /etc/pki/rootCA/newcerts/01.pem to /etc/pki/rootCA/certs/01.pem
  • Make symbolic link of /etc/pki/rootCA/certs/01.pem to /etc/pki/CA1/cacert.pem
    # ln -s /etc/pki/rootCA/certs/01.pem /etc/pki/CA1/cacert.pem
We now have our Intermediate CA-1 privatekey and public certificate. Next we prepare Intermediate CA-1 configuration and directories

First we copy /etc/pki/tls/openssl.cnf to /etc/pki/CA1/CA1.cnf
Make some changes to reflect that this is Intermediate CA-1
  • # vi /etc/pki/CA1/CA1.cnf
    Changes in section [ CA_default ]
    dir = /etc/pki/CA1
    certificate = $dir/cacert.pem
    private_key = $dir/private/cakey.pem
    crl = $dir/CA1crl.pem
    default_days = 1000
    default_md = sha512
    Changes in section [ req ]
    default_bits = 8192
    default_md = sha512
    req_extensions = v3_req
    Changes in [ req_distinguished_name ]
    as needed
    Changes in [ usr_cert ]
    basicConstraints=CA:FALSE
    keyUsage = nonRepudiation, digitalSignature, keyEncipherment
    extendedKeyUsage=serverAuth
    crlDistributionPoints = URI:http:///your-webserver/ca1.crl
    subjectAltName=${ENV::SubjectAltName} #needed by Chrome 58
    Changes in [ v3_req ]
    basicConstraints = CA:FALSE
    keyUsage = nonRepudiation, digitalSignature, keyEncipherment
    extendedKeyUsage=serverAuth
    subjectAltName=${ENV::SubjectAltName} #needed by Chrome 58
    Changes in [ v3_ca ]
    keyUsage = critical, cRLSign, keyCertSign
  • # touch /etc/pki/CA1/index.txt
  • # echo '01' > /etc/pki/CA1/serial
  • # echo '01' > /etc/pki/CA1/crlnumber
Done!!
We have our Root CA and CA1 ready to sign certificate requests. We should export Root CA and CA1 Certificate to our intended client (Your LAN Users)

    Example to sign certificate request for HTTPS Server called farseer
    We will create the request from CA1 directory (In practice this should be done on the requesting server using their own certificate request tool)
    • First, create private key (in this example, the key is encrypted. You may want to NOT encrypt it to simplify httpd startup)
      # openssl genrsa -des3 -out /etc/pki/CA1/private/farseer.pem 8192
    • Create CSR
      # SubjectAltName=DNS:farseer openssl req -new -key /etc/pki/CA1/private/farseer.pem -out /etc/pki/CA1/request/farseer.req -config /etc/pki/CA1/CA1.cnf
    • Sign the CSR
      # SubjectAltName=DNS:farseer openssl ca -config /etc/pki/CA1/CA1.cnf -infiles /etc/pki/CA1/request/farseer.req
     Then configure /etc/httpd/conf.d/ssl.conf to point to the new sslcert and private key

    In any case to revoke the signed certificate use these command

    • SubjectAltName= openssl ca -config CA1.cnf -revoke newcerts/<certificate file>
    • SubjectAltName= openssl ca -config CA1.cnf -gencrl -out crl/<crl file>
    • then copy the generated crl file to the distribution point. 
    • this CRL has expiration date that can be verified by
      openssl crl -in crl/<crl file> -noout -text


    Additional info:
    #20170505#: Google Chrome starting from version 58 has deprecated the usage of CommonName in https connection and require subjectAltName.
    I choose to use environment variable to pass this subjectAltName value to CA1.cnf file.
    There is another option to create temporary cnf file that will be unique to every certificate request and signing and supply the value in that temporary cnf file

    Additional info:
    #20140622#: Got a Fortigate100D unit, and setup SSL VPN using this steps with several modification

    1. Use only 2048 bit RSA key and sha256, when using 8196 RSA key with sha512 Fortigate refuse to get the tunnel up
    2. Change string_mask from utf8only to string_mask = default. Fortigate use PRINTABLE STRING (old standard/before 2004) in the built in CSR management. Not sure if this is necessary or not.
    3. For CA1 client signing (since Fortigate use PRINTABLE STRING and we have match it in string_mask, we need to ignore mismatch from user CSR in Windows that use utf8). Check with openssl asn1parse command.
      1. # For the CA policy
      2. [ policy_match ]
      3. countryName             = match
      4. stateOrProvinceName     = match
      5. organizationName        = match
      6. #countryName            = optional (utf8 client)
      7. #stateOrProvinceName    = optional (utf8 client)
      8. #organizationName       = optional (utf8 client)