Binary Nature where the analog and digital bits of nature connect

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Friday, 25 October 2013

Install Request Tracker 4 on Ubuntu Server

Posted on 19:39 by Unknown
The CentOS6/RT4 blog post has generated terrific feedback, so I figure an Ubuntu (and Debian) distribution port is essential.

The core components used for this tutorial:
  • Ubuntu Server 13.10
  • MySQL 5.5
  • Apache HTTP Server 2.4
  • Request Tracker 4.2

1. Operating System
Our solution will be using Ubuntu Server 13.10 (Saucy Salamander), but this tutorial can also be used with Debian (tested with Debian 7.2 "wheezy") with some minor alterations. Debian notes are included to point out the distinction. I will omit the Ubuntu Server installation process as it's beyond the scope of the tutorial. As a point of reference, my Ubuntu Server installation only includes the OpenSSH server package group.

Commands will be run as a standard user, but sudo will be used when privilege escalation is required.

$ id
uid=1000(marc) gid=1000(marc) groups=1000(marc),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),111(lpadmin),112(sambashare)

# 1.1 Updates
Make sure to update the system before we get things started.

$ sudo apt-get update && sudo apt-get dist-upgrade

# 1.2 hosts file
It's recommended a hostname entry (FQDN and short), of the local computer, is set in the hosts file. The entry should've been added during the installation but let's verify.

$ cat /etc/hosts
127.0.0.1 localhost
192.168.116.22 rt.corp.example.com rt

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

# 1.3 Network Time Protocol (NTP)
NTP is a protocol used to help synchronize your Linux system’s clock with an accurate time source. In my specific configuration, I will have my request tracker server sync with a local Active Directory domain controller (which holds the PDC emulator FSMO role) on my private network. We will need to install the ntp package, then modify the ntp.conf configuration file. Notice that I "comment out" the default public *.ubuntu.pool.ntp.org virtual cluster servers and the Ubuntu fallback entry. You may want to leave these enabled if you don't have a particular time source to sync with.

Install the ntp package.

$ sudo apt-get install ntp

Edit the NTP configuration file.

$ sudo vi /etc/ntp.conf


...
# Specify one or more NTP servers.

# Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board
# on 2011-02-08 (LP: #104525). See http://www.pool.ntp.org/join.html for
# more information.
#server 0.ubuntu.pool.ntp.org
#server 1.ubuntu.pool.ntp.org
#server 2.ubuntu.pool.ntp.org
#server 3.ubuntu.pool.ntp.org


# Use Ubuntu's ntp server as a fallback.
#server ntp.ubuntu.com

# Use internal NTP server (AD/DC01)
server 192.168.116.11 iburst

...

Restart the NTP daemon for the changes to take effect.

$ sudo service ntp restart
* Stopping NTP server ntpd [ OK ]
* Starting NTP server ntpd [ OK ]

We can verify the status of NTP by running the following command:

$ ntpq -pn
remote refid st t when poll reach delay offset jitter
==============================================================================
*192.168.116.11 206.209.110.2 2 u 38 64 7 0.329 5.795 4.726

For correct synchronization, the delay and offset values should be non-zero and the jitter value should be under 100.

# 1.4 Firewall
We will need to enable the firewall and add rules for Secure Shell (SSH), Hypertext Transfer Protocol (HTTP) and Hypertext Transfer Protocol Secure (HTTPS).

Debian: The ufw package will need to be installed (apt-get install ufw).

Enable the firewall.

$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

Get current configuration.

$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing)
New profiles: skip

Create a rule to allow inbound SSH.

$ sudo ufw allow 22/tcp
Rule added
Rule added (v6)

Create a rule to allow inbound HTTP.

$ sudo ufw allow 80/tcp
Rule added
Rule added (v6)

Create a rule to allow inbound HTTPS.

$ sudo ufw allow 443/tcp
Rule added
Rule added (v6)

Verify rules have been successfully added.

$ sudo ufw status numbered
Status: active

To Action From
-- ------ ----
[ 1] 80/tcp ALLOW IN Anywhere
[ 2] 22/tcp ALLOW IN Anywhere
[ 3] 443/tcp ALLOW IN Anywhere
[ 4] 80/tcp ALLOW IN Anywhere (v6)
[ 5] 22/tcp ALLOW IN Anywhere (v6)
[ 6] 443/tcp ALLOW IN Anywhere (v6)


A verbose method to list all rules with the ACCEPT jump target.

$ sudo iptables -S | grep -i '\-j.accept'
-A ufw-before-input -i lo -j ACCEPT
-A ufw-before-input -m state --state RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-input -p icmp -m icmp --icmp-type 3 -j ACCEPT
-A ufw-before-input -p icmp -m icmp --icmp-type 4 -j ACCEPT
-A ufw-before-input -p icmp -m icmp --icmp-type 11 -j ACCEPT
-A ufw-before-input -p icmp -m icmp --icmp-type 12 -j ACCEPT
-A ufw-before-input -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A ufw-before-input -p udp -m udp --sport 67 --dport 68 -j ACCEPT
-A ufw-before-input -d 224.0.0.251/32 -p udp -m udp --dport 5353 -j ACCEPT
-A ufw-before-input -d 239.255.255.250/32 -p udp -m udp --dport 1900 -j ACCEPT
-A ufw-before-output -o lo -j ACCEPT
-A ufw-before-output -m state --state RELATED,ESTABLISHED -j ACCEPT
-A ufw-skip-to-policy-output -j ACCEPT
-A ufw-track-output -p tcp -m state --state NEW -j ACCEPT
-A ufw-track-output -p udp -m state --state NEW -j ACCEPT
-A ufw-user-input -p tcp -m tcp --dport 22 -j ACCEPT
-A ufw-user-input -p tcp -m tcp --dport 80 -j ACCEPT
-A ufw-user-input -p tcp -m tcp --dport 443 -j ACCEPT
-A ufw-user-limit-accept -j ACCEPT

2. Database
Our solution will use MySQL for the RT data store. At the date of this post, version 5.5.32 is available in the default package repository.

# 2.1 MySQL install
Install MySQL and related components. Set a MySQL root password when prompted.

$ sudo apt-get install mysql-server mysql-client libmysqlclient-dev

# 2.2 MySQL performance and security
Double the innodb_buffer_pool_size attribute value from the default 128M to 256M. Ideally, you want to set this value to ~50% of the server's physical memory size.

$ sudo vi /etc/mysql/my.cnf


...

[mysqld]
#
# * Basic Settings
#
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address = 127.0.0.1
#
# * Fine Tuning
#
key_buffer = 16M
max_allowed_packet = 16M
thread_stack = 192K
thread_cache_size = 8
innodb_buffer_pool_size = 256M
# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
...

Now run the mysql_secure_installation script. The execution of the script is highly recommended to make MySQL production-ready from a security perspective.

$ sudo mysql_secure_installation

Restart MySQL.

$ sudo service mysql restart
mysql stop/waiting
mysql start/running, process 1844

3. Web Server
We will be using the tried-and-true Apache HTTP Server as the web server component for our solution.

# 3.1 Download and install
Download and install apache2 and other RT dependency packages.

Debian: Substitute the libgd-dev package with the libgd2-xpm-dev package.


$ sudo apt-get install make apache2 libapache2-mod-fcgid libssl-dev libyaml-perl libgd-dev libgd-gd2-perl libgraphviz-perl

4. Request Tracker (RT)
We are now at the stage of the process to get Request Tracker installed with a base configuration.

# 4.1 Users and group
Create the rt system user and group.

$ sudo adduser --system --group rt
Adding system user `rt' (UID 108) ...
Adding new group `rt' (GID 116) ...
Adding new user `rt' (UID 108) with group `rt' ...
Creating home directory `/home/rt' ...

Add the www-data (Apache) user to the rt group.

$ sudo usermod -aG rt www-data

# 4.2 Stage RT build environment
Download the latest RT 4 compressed tarball, unpack and navigate into the directory.

$ cd
$ wget http://download.bestpractical.com/pub/rt/release/rt.tar.gz
$ tar xf rt.tar.gz -C /tmp
$ cd /tmp/rt-*

# 4.3 RT Configure script
We will be running the configure script with a number of default and explicit options. Since we haven't defined it otherwise, our install path location will be /opt/rt4.

$ ./configure --with-web-user=www-data --with-web-group=www-data --enable-graphviz --enable-gd

# 4.4 Perl CPAN.pm
The installation of RT requires we enter the Perl CPAN.pm shell before running the RT dependency checker. Within the shell, we will set the configuration to automate the majority of the module installs.

$ sudo cpan

CPAN.pm requires configuration, but most of it can be done automatically.
If you answer 'no' below, you will enter an interactive dialog for each
configuration option instead.

Would you like to configure as much as possible automatically? [yes] <enter>
...
Would you like me to automatically choose some CPAN mirror
sites for you? (This means connecting to the Internet) [yes] <enter>
...
cpan[1]> o conf prerequisites_policy follow
cpan[2]> o conf build_requires_install_policy yes
cpan[3]> o conf commit
cpan[4]> q

# 4.5 RT Perl dependencies
For the few times you may be prompted for an install, select the default choice. Iterate the make fixdeps command until you reach the output statement All dependencies have been found. It may take more than a single pass to successfully get and install all the modules.

$ make testdeps
$ sudo make fixdeps

Verify.

$ make testdeps
/usr/bin/perl ./sbin/rt-test-dependencies --verbose --with-mysql --with-fastcgi
perl:
>=5.10.1(5.14.2) ...found
users:
rt group (rt) ...found
bin owner (root) ...found
libs owner (root) ...found
libs group (bin) ...found
web owner (www-data) ...found
web group (www-data) ...found
CLI dependencies:
Text::ParseWords ...found
Term::ReadKey ...found
Getopt::Long >= 2.24 ...found
HTTP::Request::Common ...found
Term::ReadLine ...found
LWP ...found
CORE dependencies:
Storable >= 2.08 ...found
Encode >= 2.39 ...found
Crypt::Eksblowfish ...found
Module::Versions::Report >= 1.05 ...found
List::MoreUtils ...found
Errno ...found
DBI >= 1.37 ...found
Devel::StackTrace >= 1.19 ...found
HTTP::Message >= 6.0 ...found
Text::Password::Pronounceable ...found
Devel::GlobalDestruction ...found
Time::ParseDate ...found
IPC::Run3 ...found
Tree::Simple >= 1.04 ...found
HTML::Scrubber >= 0.08 ...found
HTML::Quoted ...found
Sys::Syslog >= 0.16 ...found
Mail::Mailer >= 1.57 ...found
Data::GUID ...found
HTML::Mason >= 1.43 ...found
HTML::Entities ...found
LWP::Simple ...found
Symbol::Global::Name >= 0.04 ...found
DateTime::Format::Natural >= 0.67 ...found
Plack >= 1.0002 ...found
File::Glob ...found
Class::Accessor >= 0.34 ...found
Text::Wrapper ...found
Regexp::Common::net::CIDR ...found
Log::Dispatch >= 2.30 ...found
HTML::FormatText::WithLinks::AndTables ...found
DateTime >= 0.44 ...found
CGI::Emulate::PSGI ...found
Text::Quoted >= 2.07 ...found
Regexp::IPv6 ...found
CGI >= 3.38 ...found
CSS::Squish >= 0.06 ...found
DateTime::Locale >= 0.40 ...found
CGI::PSGI >= 0.12 ...found
Apache::Session >= 1.53 ...found
Date::Extract >= 0.02 ...found
Digest::SHA ...found
HTML::Mason::PSGIHandler >= 0.52 ...found
MIME::Entity >= 5.504 ...found
Locale::Maketext::Lexicon >= 0.32 ...found
Module::Refresh >= 0.03 ...found
Role::Basic >= 0.12 ...found
Digest::base ...found
File::Temp >= 0.19 ...found
Date::Manip ...found
Locale::Maketext >= 1.06 ...found
HTML::RewriteAttributes >= 0.05 ...found
Text::Template >= 1.44 ...found
CGI::Cookie >= 1.20 ...found
Scalar::Util ...found
XML::RSS >= 1.05 ...found
Text::WikiFormat >= 0.76 ...found
File::Spec >= 0.8 ...found
DBIx::SearchBuilder >= 1.65 ...found
File::ShareDir ...found
Regexp::Common ...found
Digest::MD5 >= 2.27 ...found
HTML::FormatText::WithLinks >= 0.14 ...found
Mail::Header >= 2.12 ...found
Locale::Maketext::Fuzzy >= 0.11 ...found
Time::HiRes ...found
Email::Address::List ...found
Net::CIDR ...found
JSON ...found
UNIVERSAL::require ...found
Email::Address >= 1.897 ...found
Plack::Handler::Starlet ...found
DASHBOARDS dependencies:
URI::QueryParam ...found
URI >= 1.59 ...found
MIME::Types ...found
FASTCGI dependencies:
FCGI::ProcManager ...found
FCGI >= 0.74 ...found
GD dependencies:
GD::Text ...found
GD ...found
GD::Graph >= 1.47 ...found
GPG dependencies:
File::Which ...found
PerlIO::eol ...found
GnuPG::Interface ...found
GRAPHVIZ dependencies:
IPC::Run >= 0.90 ...found
GraphViz ...found
ICAL dependencies:
Data::ICal ...found
MAILGATE dependencies:
Pod::Usage ...found
LWP::UserAgent >= 6.0 ...found
Crypt::SSLeay ...found
Getopt::Long ...found
Net::SSL ...found
LWP::Protocol::https ...found
Mozilla::CA ...found
MYSQL dependencies:
DBD::mysql >= 2.1018 ...found
SMIME dependencies:
String::ShellQuote ...found
File::Which ...found
Crypt::X509 ...found
USERLOGO dependencies:
Convert::Color ...found

All dependencies have been found.

# 4.6 Install RT and initialize RT database
After we have verified the Perl dependencies for RT have been met, we can start the install.
$ sudo make install
...
Congratulations. RT is now installed.


You must now configure RT by editing /opt/rt4/etc/RT_SiteConfig.pm.

(You will definitely need to set RT's database password in
/opt/rt4/etc/RT_SiteConfig.pm before continuing. Not doing so could be
very dangerous. Note that you do not have to manually add a
database user or set up a database for RT. These actions will be
taken care of in the next step.)

After that, you need to initialize RT's database by running
'make initialize-database'

Let's now run the following command to create the RT database and user. Enter the MySQL root password when prompted.

$ sudo make initialize-database
/usr/bin/perl -I/opt/rt4/local/lib -I/opt/rt4/lib sbin/rt-setup-database --action init --prompt-for-dba-password
In order to create or update your RT database, this script needs to connect to your mysql instance on localhost (port '') as root
Please specify that user's database password below. If the user has no database
password, just press return.

Password: <your_MySQL_root_password>
Working with:
Type: mysql
Host: localhost
Port:
Name: rt4
User: rt_user
DBA: root
Now creating a mysql database rt4 for RT.
Done.
Now populating database schema.
Done.
Now inserting database ACLs.
Granting access to rt_user@'localhost' on rt4.
Done.
Now inserting RT core system objects.
Done.
Now inserting data.
Done inserting data.
Done.

# 4.7 Configure Apache for RT
Set HTTP to HTTPS redirect for all incoming HTTP requests.

Debian: The 000-default.conf file is named default.


$ sudo vi /etc/apache2/sites-available/000-default.conf


<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
ServerName rt.corp.example.com:80
Redirect / https://rt.corp.example.com/


#ServerAdmin webmaster@localhost
#DocumentRoot /var/www

# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

...

Create the rt site configuration file.

Debian: The default-ssl.conf file is named default-ssl, and also remove the .conf extension for the rt.conf filename (e.g. rt.conf -> rt).


$ sudo cp /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-available/rt.conf

Edit the rt site configuration file.

Debian: Take note of the Location container in regards to Apache version differences. Modify accordingly.


$ sudo vi /etc/apache2/sites-available/rt.conf


<IfModule mod_ssl.c>
<VirtualHost _default_:443>
# Request Tracker
ServerName rt.corp.example.com:443
AddDefaultCharset UTF-8
DocumentRoot /opt/rt4/share/html
Alias /NoAuth/images/ /opt/rt4/share/html/NoAuth/images/
ScriptAlias / /opt/rt4/sbin/rt-server.fcgi/
<Location />
## Apache version < 2.4 (e.g. Debian 7.2)
#Order allow,deny
#Allow from all
## Apache 2.4
Require all granted
</Location>
<Directory "/opt/rt4/sbin">
SSLOptions +StdEnvVars
</Directory>


# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
...

Enable the ssl and fcgid modules. Note the fcgid module may already be enabled.

$ sudo a2enmod ssl fcgid
Considering dependency setenvif for ssl:
Module setenvif already enabled
Considering dependency mime for ssl:
Module mime already enabled
Considering dependency socache_shmcb for ssl:
Enabling module socache_shmcb.
Enabling module ssl.
See /usr/share/doc/apache2/README.Debian.gz on how to configure SSL and create self-signed certificates.
Module fcgid already enabled
To activate the new configuration, you need to run:
service apache2 restart

Enable the rt site.

$ sudo a2ensite rt
Enabling site rt.
To activate the new configuration, you need to run:
service apache2 reload

Verify the Apache configuration.

$ sudo apachectl configtest
Syntax OK

Restart Apache.

$ sudo service apache2 restart
* Restarting web server apache2 [ OK ]

# 4.8 RT_SiteConfig.pm file
Request Tracker is very customizable, but the following base configuration settings should get you started.

$ sudo vi /opt/rt4/etc/RT_SiteConfig.pm

...
# You must restart your webserver after making changes to this file.

Set( $rtname, 'example.com');
Set( $Organization, 'corp.example.com');
Set( $Timezone, 'US/Pacific');
Set( $WebDomain, 'rt.corp.example.com');
Set( $WebPort, 443);
Set( $WebPath, '');


# You must install Plugins on your own, this is only an example
...

Restart Apache.

$ sudo service apache2 restart
* Restarting web server apache2 [ OK ]

# 4.9 Moment of truth
Open a web browser and enter http://rt.corp.example.com (or https://rt.corp.example.com) into the web address field, then press the enter key to establish a secure connection to the RT server. If everything has been installed and configured correctly, you should be presented with the RT Login page.

The default administrative credentials are:
  • Username: root
  • Password: password
5. Post-Install
At this point, we should have a basic RT server up and running, but we still need to perform some additional post-install tasks for Request Tracker.

# 5.1 MySQL
We need to set a password for the RT database user (rt_user). The task requires that we add the password to the RT configuration file and also set it in MySQL.

Add the $DatabasePassword key and corresponding value in the RT_SiteConfig.pm file.
$ sudo vi /opt/rt4/etc/RT_SiteConfig.pm


...

Set( $rtname, 'example.com');
Set( $Organization, 'corp.example.com');
Set( $Timezone, 'US/Pacific');
Set( $WebDomain, 'rt.corp.example.com');
Set( $WebPort, 443);
Set( $WebPath, '');
Set( $DatabasePassword, 'Pa$$w0rD!');

...

And now in MySQL.
$ mysql -u root -p
Enter password: <your_MySQL_root_password>
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 46
Server version: 5.5.34-0ubuntu0.13.10.1 (Ubuntu)

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SET PASSWORD FOR 'rt_user'@'localhost' = PASSWORD('Pa$$w0rD!');
Query OK, 0 rows affected (0.00 sec)

mysql> \q
Bye

Restart MySQL.

$ sudo service mysql restart
mysql stop/waiting
mysql start/running, process 1844

# 5.2 mod_fcgid
As per RT documentation:

WARNING: Before mod_fcgid 2.3.6, the maximum request size was 1GB. Starting in 2.3.6, this is now 128Kb. This is unlikely to be large enough for any RT install that handles attachments.

$ sudo vi /etc/apache2/mods-available/fcgid.conf


<IfModule mod_fcgid.c>
FcgidConnectTimeout 20
# Request Tracker
FcgidMaxRequestLen 1073741824


<IfModule mod_mime.c>
AddHandler fcgid-script .fcgi
</IfModule>
</IfModule>

Restart Apache.

$ sudo service apache2 restart
* Restarting web server apache2 [ OK ]


Read More
Posted in Apache, Linux, MySQL, RT | No comments

Saturday, 21 September 2013

Integrate VMware Fusion with GNS3 on your Mac

Posted on 16:20 by Unknown

At long last, we can finally integrate VMware Fusion with GNS3. VMware Workstation for Windows and Linux has had this capability for quite some time, but Mac users were limited to VirtualBox or Parallels for GNS3 integration. Not to take anything away from those virtualization products, but VMware is the virtualization standard in regards to broad industry support and compatibility.

The following components were used for this tutorial:
  • Mac OS X 10.8 (also tested with Mac OS X 10.9)
  • VMware Fusion 6.0 Professional
  • GNS3
  • TunTap

This tutorial assumes you have, at the very least, a basic amount of experience with each of the listed components. You can refer to my previous post Install and configure GNS3 with TunTap on the Mac for the GNS3 and TunTap elements. Another prerequisite is that all components are installed and set with a base configuration.

1. VMware Fusion
VMware Fusion 6 is a hard requirement for this tutorial. VMware has made modifications to the VMnet virtual switches (in version 6) to allow Ethernet bridging with other virtual network interfaces (e.g. TAP). If you use this tutorial with version 5 or below, you may encounter kernel panics on your Mac. You've been warned. :-)

I'm also using VMware Fusion 6.0 Professional in my setup. The non-Professional edition does not include the GUI Network Editor. A possible solution for the "vanilla" edition of VMware Fusion 6.0 is the UBER Network Fuser tool by Nicholas Weaver. I haven't tested the tool with VMware Fusion 6.0, so a little research on your part may be in order.

# 1.1 Virtual Network Switches
Our network configuration will use two host-only network switches. A host-only network (switch) is a network that is completely contained within the host computer. Host-only networking provides a network connection between the virtual machine and the host system by using a virtual network adapter that is visible on the host operating system. vmnet1 is available by default and is listed as Private to my Mac in the GUI. Let's now add the other one.
  1. Open the Preferences window for VMware Fusion Professional.
  2. Select Network.
  3. Select the + symbol to add a new virtual switch. In my example, vmnet5 is added. As the following screenshot shows, we will leave the Allow virtual machines on this network to connect to external networks (using NAT) and Provide addresses on this network via DHCP options unchecked.
  4. Select the Apply button to save the setting, then close the Preferences window.
FYI: vmnet1 and vmnet8 are the default host-only and NAT virtual switches, respectively. vmnet8 is listed as Share with my Mac in the GUI.

We can list all network interfaces (physical and virtual) with the ifconfig command from the terminal.

$ ifconfig

# 1.2 Virtual Machines
This section will assume you've already installed the operating system in each of your virtual machines, or you have opted to import a virtual appliance. Just verify a vNIC is connected to the correct virtual network (switch). In my example, I have both a Windows and Linux virtual machine. The Windows VM is linked to the vmnet1 switch and the Linux VM will use vmnet5.
After each virtual machine's hardware profile is set, we can go ahead and start the VMs.

Set the network configuration in each operating system:
  • Static IP Address
  • Subnet Mask
  • Gateway
  • DNS Server(s)
My configuration for each VM:

2. GNS3
With the VMware Fusion section complete, we can now focus on GNS3. The remainder of the tutorial will be referencing this network diagram:

Go ahead and add the GNS3 objects to a new project. My configuration has R1 using a Cisco 3725 IOS image but feel free to use any GNS3-compatible IOS image for your virtual router. SW1 and SW2 are simple GNS3 Ethernet switches. The VMs are Host objects (not VirtualBox guest), and the object that looks like a cloud is ... wait for it ... a Cloud object.

# 2.1 Cloud and Hosts
We need to configure each of the Cloud and Host objects before we wire them to the switches. Each object will be using a TAP virtual network interface. Let's start with the Cloud object.
  1. Right-click the Cloud object.
  2. Select Configure.
  3. Select the subnode (ex. C1).
  4. Select NIO TAP.
  5. Enter /dev/tap0 into the top field.
  6. Select the Add button to add the interface.
  7. Select the Apply button to save the setting.
  8. Then select the OK button to close the window.
Repeat the steps for each of the Host objects. Just substitute the tapX value. The Windows VM will use /dev/tap1 and the Linux VM will use /dev/tap2. These are labeled in the network diagram screenshot.

Connect all the objects with Fast Ethernet links.

By linking the Cloud and Host objects with the switches, it should have brought up the TAP network interfaces on the physical Mac host. Let's check. Run the following commands from the terminal:

$ ifconfig tap0
tap0: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 02:e9:2d:82:4d:f8
open (pid 5333)
$ ifconfig tap1
tap1: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether ee:47:b5:07:63:ea
open (pid 5333)
$ ifconfig tap2
tap2: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 0e:6d:9b:0e:f9:cf
open (pid 5333)

# 2.2 R1 Router
Start the R1 router. Emulate a console connection by establishing a telnet session to the virtual device. In my configuration, R1 (Dynamips) is listening on port 2101, so I run the following command in the terminal:

$ telnet localhost 2101

We now need to set the network configuration for the Fast Ethernet interfaces in IOS. In my example:

R1# conf t
R1(config)# int f0/0
R1(config-if)# ip addr 10.11.1.254 255.255.255.0
R1(config-if)# no shut
R1(config-if)# int f0/1
R1(config-if)# ip addr 172.16.195.254 255.255.255.0
R1(config-if)# no shut
R1(config-if)# end
R1# copy run start

Verify the configuration and state of the Fast Ethernet interfaces.

R1# sh run | sec int
interface FastEthernet0/0
ip address 10.11.1.254 255.255.255.0
duplex auto
speed auto
interface FastEthernet0/1
ip address 172.16.195.254 255.255.255.0
duplex auto
speed auto
R1# sh ip int br
Interface IP-Address OK? Method Status Protocol
FastEthernet0/0 10.11.1.254 YES manual up up
FastEthernet0/1 172.16.195.254 YES manual up up

3. Ethernet Bridge
So now the big question is: How do we integrate our Windows and Linux VMs with the GNS3 environment? The answer is by creating an Ethernet bridge. This will essentially bind two separate virtual network segments (vmnetX and tapX) into a single virtual network interface attached to the Mac host. We will be creating two bridge interfaces. One for the Windows VM and the other for the Linux VM.

# 3.1 Bridge for Windows VM
We first need to clear the IP configuration for the vmnet1 virtual network interface before adding it as a member to the first bridge interface. Run the following from the terminal:

$ sudo ifconfig vmnet1 down
$ sudo ifconfig vmnet1 inet delete

Create the first bridge interface for the Windows VM.

$ sudo ifconfig bridge0 create

Add the member network interfaces (vmnet1 and tap1) to the bridge.

$ sudo ifconfig bridge0 addm vmnet1
$ sudo ifconfig bridge0 addm tap1

Bring the bridge interface up.

$ sudo ifconfig bridge0 up

Verify the bridge0 configuration.

$ ifconfig bridge0
bridge0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether ac:de:48:ed:da:5a
Configuration:
priority 0 hellotime 0 fwddelay 0 maxage 0
ipfilter disabled flags 0x2
member: vmnet1 flags=3<LEARNING,DISCOVER>
port 7 priority 0 path cost 0
member: tap1 flags=3<LEARNING,DISCOVER>
port 14 priority 0 path cost 0
Address cache (max cache: 100, timeout: 1200):

# 3.2 Bridge for Linux VM
Just like with vmnet1, we need to clear the IP configuration for the vmnet5 virtual network interface before adding it as a member to the second bridge interface. Run the following from the terminal:

$ sudo ifconfig vmnet5 down
$ sudo ifconfig vmnet5 inet delete

Create the second bridge interface for the Linux VM.

$ sudo ifconfig bridge1 create

Add the member network interfaces (vmnet5 and tap2) to the bridge.

$ sudo ifconfig bridge1 addm vmnet5
$ sudo ifconfig bridge1 addm tap2

Bring the bridge interface up.

$ sudo ifconfig bridge1 up

Verify the bridge1 configuration.

$ ifconfig bridge1
bridge1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether ac:de:48:6d:28:37
Configuration:
priority 0 hellotime 0 fwddelay 0 maxage 0
ipfilter disabled flags 0x2
member: vmnet5 flags=3<LEARNING,DISCOVER>
port 9 priority 0 path cost 0
member: tap2 flags=3<LEARNING,DISCOVER>
port 15 priority 0 path cost 0
Address cache (max cache: 100, timeout: 1200):
c2:0:14:d5:0:1 tap2 1158 flags=0<>

4. Tap0 Interface
The tap0 interface will not be part of a bridge interface, but we still need to set the IP configuration for it as it will be a node interface on the 10.11.1.0/24 network.

$ sudo ifconfig tap0 inet 10.11.1.1/24 up

5. Testing and Verification
At this stage, we should be ready to do some basic connectivity testing.

Ping the Linux VM from the Windows VM.

C:\> ping 172.16.195.11

Pinging 172.16.195.11 with 32 bytes of data:
Reply from 172.16.195.11: bytes=32 time=1ms TTL=64
Reply from 172.16.195.11: bytes=32 time<1ms TTL=64
Reply from 172.16.195.11: bytes=32 time<1ms TTL=64
Reply from 172.16.195.11: bytes=32 time<1ms TTL=64

Ping statistics for 172.16.195.11:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 1ms, Average = 0ms


Ping the R1 f0/1 interface (default gateway) from the Windows VM.

C:\> ping 172.16.195.254

Pinging 172.16.195.254 with 32 bytes of data:
Reply from 172.16.195.254: bytes=32 time=16ms TTL=255
Reply from 172.16.195.254: bytes=32 time=9ms TTL=255
Reply from 172.16.195.254: bytes=32 time=6ms TTL=255
Reply from 172.16.195.254: bytes=32 time=5ms TTL=255

Ping statistics for 172.16.195.254:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 5ms, Maximum = 16ms, Average = 9ms


Ping the R1 f0/0 interface from the Windows VM.

C:\> ping 10.11.1.254

Pinging 10.11.1.254 with 32 bytes of data:
Reply from 10.11.1.254: bytes=32 time=17ms TTL=255
Reply from 10.11.1.254: bytes=32 time=9ms TTL=255
Reply from 10.11.1.254: bytes=32 time=6ms TTL=255
Reply from 10.11.1.254: bytes=32 time=7ms TTL=255

Ping statistics for 10.11.1.254:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 6ms, Maximum = 17ms, Average = 9ms


Everything looks good so far. Let's now try to ping the tap0 network interface.

C:\> ping 10.11.1.1

Pinging 10.11.1.1 with 32 bytes of data:
Request timed out.
Request timed out.
Request timed out.
Request timed out.

Ping statistics for 10.11.1.1:
Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),


Now, why did it fail? Let's break it down logically. The Windows VM can ping each interface on its own subnet and also the R1 f0/0 interface on the remote 10.11.1.0/24 subnet, but for some reason it doesn't receive an ICMP Echo reply from tap0. Remember that routing is a "two-way street". The packets may get to the destination, but do they know how to get back? R1 knows about both subnets as they are direct (connected) routes in the routing table, so let us think from the viewpoint of the tap0 interface on the Mac. Does it know how to get to the remote subnet? Let's check the routing table, on the Mac, for the 172.16.195.0 network entry. Run the following command from the terminal:

$ netstat -rn | grep 172.16.195

Nothing. Therein lies the problem. The Mac needs a route for the remote 172.16.195.0 subnet. Create the static route by running the following command from the terminal:

$ sudo route -nv add -net 172.16.195.0 10.11.1.254
u: inet 172.16.195.0; u: inet 10.11.1.254; RTM_ADD: Add Route: len 132, pid: 0, seq 1, errno 0, flags:<UP,GATEWAY,STATIC>
locks: inits:
sockaddrs: <DST,GATEWAY,NETMASK>
172.16.195.0 10.11.1.254 (0) 0 ffff ff
add net 172.16.195.0: gateway 10.11.1.254

Verify.

$ netstat -rn | egrep 'Use|172.16.195'
Destination Gateway Flags Refs Use Netif Expire
172.16.195/24 10.11.1.254 UGSc 0 0 tap0

Let's ping the tap0 interface again from the Windows VM.

C:\> ping 10.11.1.1

Pinging 10.11.1.1 with 32 bytes of data:
Reply from 10.11.1.1: bytes=32 time=35ms TTL=63
Reply from 10.11.1.1: bytes=32 time=12ms TTL=63
Reply from 10.11.1.1: bytes=32 time=15ms TTL=63
Reply from 10.11.1.1: bytes=32 time=13ms TTL=63

Ping statistics for 10.11.1.1:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 12ms, Maximum = 35ms, Average = 18ms


We should now have full connectivity among all devices in our virtual network.

6. No Man Is An Island
Let's take this a step further. Let's extend the reach of our virtual network to the Internet. We have at least two different methods of implementing this. We can either configure NAT on the R1 router (and also have the physical Mac host perform routing) or have our physical Mac host perform both the NAT and IP routing process. We will use the latter method.

Note: A wired (i.e., no Wi-Fi) Ethernet connection is required.

# 6.1 IP Routing
You may be thinking: How can my Mac route packets with only a single, active, physical network interface with a single IP address? Think virtual. The tap0 network interface is the link to our virtual network. It is the "other arm", so to speak. Get the current IP Routing configuration by running the following command in the terminal:

$ sysctl -a | grep ip.forwarding
net.inet.ip.forwarding: 0

If the value is 0, enable IP forwarding. When IP forwarding is enabled, the operating system kernel will act as a router.

$ sudo sysctl -w net.inet.ip.forwarding=1
net.inet.ip.forwarding: 0 -> 1

# 6.2 NAT
Start the Network Address Translation (NAT) daemon with these options. The interface parameter value being the wired Ethernet network interface that accesses the Internet.

$ sudo natd -interface en0 -use_sockets -same_ports -unregistered_only -dynamic -clamp_mss

Verify the NAT daemon status.

$ ps aux | grep natd | grep en0
root 7424 0.0 0.0 2432924 416 ?? Ss 4:31PM 0:00.48 natd -interface en0 -use_sockets -same_ports -unregistered_only -dynamic -clamp_mss

# 6.3 Firewall
The IP firewall will also need to be enabled. Is the firewall already enabled?

$ sysctl -a | grep ip.fw.en
net.inet.ip.fw.enable: 1

If the value is 0, we can enable it with the sysctl utility.

$ sudo sysctl -w net.inet.ip.fw.enable=1

Add a firewall rule for the NAT daemon. Remember to modify the network interface value following the via token if need be.

$ sudo ipfw add divert natd ip from any to any via en0
00100 divert 8668 ip from any to any via en0

Verify the firewall rule has been added.

$ sudo ipfw show
00100 10 622 divert 8668 ip from any to any via en0
65535 10390254 10716213934 allow ip from any to any

# 6.4 R1 Router
IOS for R1 will also need to be configured before R1 and the VMs can access the Internet.

Emulate a console connection by establishing a telnet session to the virtual device. In my configuration, R1 is listening on port 2101, so I run the following command in the terminal:

$ telnet localhost 2101

Enable DNS translation and set to the Google Public DNS.

R1# conf t
R1(config)# ip domain-lookup
R1(config)# ip name-server 8.8.8.8

And finally, add a static default route for any unknown destination. Use the tap0 IP address for the next-hop IP address value. Also, save the configuration.

R1(config)# ip route 0.0.0.0 0.0.0.0 10.11.1.1
R1(config)# end
R1# copy run start

# 6.5 One More Test
The moment of truth.

# mtr www.google.com
Read More
Posted in Cisco, GNS3, Linux, Mac, VMware, Windows | No comments

Tuesday, 13 August 2013

PowerShell Function for Windows System Memory Statistics

Posted on 00:27 by Unknown
Memory is one of the four primary hardware resources an operating system manages. The other three are cpu, disk, and network. Analysis of system memory statistics is a common task for any Windows system administrator as odd behavior can occur when left unchecked. A few built-in tools (Task Manager, Resource Monitor, and Performance Monitor) may be sufficient depending on what memory metrics you need to track, but many sysadmins eventually turn to the tool often referred to as “Task Manager on steroids”.

Process Explorer provides transparency into the Windows operating system from the scope of a single process to the system as a whole. I often use the System Information feature when I need a broad, but also detailed, overview of the “big four” components.
System Information
Process Explorer is an excellent solution when used interactively on the local computer, but what if you prefer to gather system memory statistics for hundreds of remote computers all from the comfort of your management workstation? Think large-scale fan-out remoting.

Design and Implementation
The following tables display the system memory attributes the custom PowerShell object type will be comprised of. As you well may notice, they’re essentially the same properties from the Commit Charge, Physical Memory, and Kernel Memory sections of Process Explorer’s System Information Memory tab.

Commit Charge
AttributeDefinition
CurrentAmount of committed virtual memory. Committed memory is physical memory for which space has been reserved on the disk paging file in case it must be written back to disk.
LimitAmount of virtual memory that can be committed without having to extend the paging file(s). If the paging file(s) are be expanded, the CommitLimit value increases accordingly.
PeakThe maximum amount of memory in the committed state since the last system reboot.

Physical Memory
AttributeDefinition
TotalThe amount of actual physical memory.
AvailableThe amount of physical memory currently available. This is the amount of physical memory that can be immediately reused without having to write its contents to disk first.
Cache Working SetShows the sum of the values of System Cache Resident Bytes, System Driver Resident Bytes, System Code Resident Bytes, and Pool Paged Resident Bytes.
Kernel Working SetShows the size of operating system code currently in physical memory that can be written to disk when not in use.
Driver Working SetShows the size of pageable physical memory being used by device drivers. It is the working set (physical memory area) of the drivers.

Kernel Memory
AttributeDefinition
Paged Working SetShows the current size of the paged pool. Space used by the paged and nonpaged pools is taken from physical memory, so a pool that is too large denies memory space to processes.
Paged VirtualThe memory currently in the paged kernel pool.
NonpagedThe memory currently in the nonpaged kernel pool.


I've also incorporated some inline C# code within the PowerShell function. When I was designing the function, I figured I would be able to retrieve all necessary data from WMI for the properties of the object, and that is true for all except one.

The Peak Commit Charge property value can only be programmatically accessed from the Windows API (PERFORMANCE_INFORMATION structure) with the GetPerformanceInfo PSAPI function. PowerShell (and more specifically C#) can’t do this directly. Platform Invocation Services (P/Invoke) is required. Luckily, Antonio Bakula created a C# wrapper for the GetPerformanceInfo function, so our PowerShell function can leverage his code.

The original design had the PowerShell function output a single custom PS object type that would encase all properties, but there is a slight performance penalty with instantiating the Win32_PerfRawData_PerfOS_Memory type. The operation needs to load performance monitor counters which translates into longer runtime of the command. You can test this yourself by running the following command:

PS> Measure-Command { gwmi Win32_PerfRawData_PerfOS_Memory } | fl sec*,mill*

On my Windows 2008 R2 Server test system, it takes an average of five seconds to complete the operation, but it only takes an average of two seconds for my Windows 2012 Server test system. This happens to be a minor nuisance for a single computer, but those seconds start to add up when accessing dozens of remote computers for a single batch job. It should also be noted this only happens with the initial launch of the command. The process is cached (and/or counters stay loaded) for a little while (~10 minutes), so each successive execution of the command is nearly instantaneous within that timespan.

My solution is to have the function output two separate custom PS object types. One is “light” and the other is “heavy”. The default output is the "light" object. If you run the function with the -Detailed option, it will output the "heavy" object with all properties. The primary differences being the "light" object has a subset of the "heavy" object properties, but it only references data from the object created with the inline C# code. It is the preferred object to use if all you need are core memory statistics and execution speed is essential. If you require "everything but the kitchen sink" memory statistics, then the "heavy" object is the way to go.

PS> (Get-Memory).pstypenames[0]
BinaryNature.Memory
PS> (Get-Memory -Detailed).pstypenames[0]
BinaryNature.MemoryDetailed

The Usage section will go over examples of both.

001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 084 085 086 087 088 089 090 091 092 093 094 095 096 097 098 099 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
function Get-Memory{ [CmdletBinding()] param ( [switch]$Detailed, [switch]$Format ) $signature = @' /* * Item: Windows PSAPI GetPerformanceInfo C# Wrapper * Source: http://www.antoniob.com/windows-psapi-getperformanceinfo-csharp-wrapper.html * Author: Antonio Bakula */ using System; using System.Runtime.InteropServices; public struct PerfomanceInfoData { public Int64 CommitTotalPages; public Int64 CommitLimitPages; public Int64 CommitPeakPages; public Int64 PhysicalTotalBytes; public Int64 PhysicalAvailableBytes; public Int64 SystemCacheBytes; public Int64 KernelTotalBytes; public Int64 KernelPagedBytes; public Int64 KernelNonPagedBytes; public Int64 PageSizeBytes; public int HandlesCount; public int ProcessCount; public int ThreadCount; } public static class PsApiWrapper { [DllImport("psapi.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool GetPerformanceInfo([Out] out PsApiPerformanceInformation PerformanceInformation, [In] int Size); [StructLayout(LayoutKind.Sequential)] public struct PsApiPerformanceInformation { public int Size; public IntPtr CommitTotal; public IntPtr CommitLimit; public IntPtr CommitPeak; public IntPtr PhysicalTotal; public IntPtr PhysicalAvailable; public IntPtr SystemCache; public IntPtr KernelTotal; public IntPtr KernelPaged; public IntPtr KernelNonPaged; public IntPtr PageSize; public int HandlesCount; public int ProcessCount; public int ThreadCount; } public static PerfomanceInfoData GetPerformanceInfo() { PerfomanceInfoData data = new PerfomanceInfoData(); PsApiPerformanceInformation perfInfo = new PsApiPerformanceInformation(); if (GetPerformanceInfo(out perfInfo, Marshal.SizeOf(perfInfo))) { Int64 pageSize = perfInfo.PageSize.ToInt64(); // data in bytes data.CommitTotalPages = perfInfo.CommitTotal.ToInt64() * pageSize; data.CommitLimitPages = perfInfo.CommitLimit.ToInt64() * pageSize; data.CommitPeakPages = perfInfo.CommitPeak.ToInt64() * pageSize; data.PhysicalTotalBytes = perfInfo.PhysicalTotal.ToInt64() * pageSize; data.PhysicalAvailableBytes = perfInfo.PhysicalAvailable.ToInt64() * pageSize; data.KernelPagedBytes = perfInfo.KernelPaged.ToInt64() * pageSize; data.KernelNonPagedBytes = perfInfo.KernelNonPaged.ToInt64() * pageSize; } return data; } } '@ function Format-HumanReadable { param ($size) switch ($size) { {$_ -ge 1PB}{"{0:#.#'P'}" -f ($size / 1PB); break} {$_ -ge 1TB}{"{0:#.#'T'}" -f ($size / 1TB); break} {$_ -ge 1GB}{"{0:#.#'G'}" -f ($size / 1GB); break} {$_ -ge 1MB}{"{0:#.#'M'}" -f ($size / 1MB); break} {$_ -ge 1KB}{"{0:#'K'}" -f ($size / 1KB); break} default {"{0}" -f ($size) + "B"} } } # Create PerformanceInfoData object Add-Type -TypeDefinition $signature [PerfomanceInfoData]$w32perf = [PsApiWrapper]::GetPerformanceInfo() if ($Detailed) { try { # Create Win32_PerfRawData_PerfOS_Memory object $query = 'SELECT * FROM Win32_PerfRawData_PerfOS_Memory' $wmimem = Get-WmiObject -Query $query -ErrorAction Stop # Create "detailed" PS memory object # Value in bytes for memory attributes $memd = New-Object -TypeName PSObject -Property @{ TotalPhysicalMem=$w32perf.PhysicalTotalBytes AvailPhysicalMem=$w32perf.PhysicalAvailableBytes CacheWorkingSet=[long]$wmimem.CacheBytes KernelWorkingSet=[long]$wmimem.SystemCodeResidentBytes DriverWorkingSet=[long]$wmimem.SystemDriverResidentBytes CommitCurrent=$w32perf.CommitTotalPages CommitLimit=$w32perf.CommitLimitPages CommitPeak=$w32perf.CommitPeakPages PagedWorkingSet=[long]$wmimem.PoolPagedResidentBytes PagedVirtual=$w32perf.KernelPagedBytes Nonpaged=$w32perf.KernelNonPagedBytes Computer=$env:COMPUTERNAME } } catch { $msg = ("Error: {0}" -f $_.Exception.Message) Write-Warning $msg } if ($Format) { # Format output in human-readable form # End of PS pipeline/format right rule option Write-Output '-------------' Write-Output 'Commit Charge' Write-Output '-------------' "Current : $(Format-HumanReadable $memd.CommitCurrent)" "Limit`t : $(Format-HumanReadable $memd.CommitLimit)" "Peak`t : $(Format-HumanReadable $memd.CommitPeak)" "Peak/Limit : $("{0:P2}" ` -f ($memd.CommitPeak / $memd.CommitLimit))" "Curr/Limit : $("{0:P2}" ` -f ($memd.CommitCurrent / $memd.CommitLimit))" [Environment]::NewLine Write-Output '---------------' Write-Output 'Physical Memory' Write-Output '---------------' "Total`t : $(Format-HumanReadable $memd.TotalPhysicalMem)" "Available : $(Format-HumanReadable $memd.AvailPhysicalMem)" "CacheWS`t : $(Format-HumanReadable $memd.CacheWorkingSet)" "KernelWS : $(Format-HumanReadable $memd.KernelWorkingSet)" "DriverWS : $(Format-HumanReadable $memd.DriverWorkingSet)" [Environment]::NewLine Write-Output '-------------' Write-Output 'Kernel Memory' Write-Output '-------------' "PagedWS : $(Format-HumanReadable $memd.PagedWorkingSet)" "PagedVirt : $(Format-HumanReadable $memd.PagedVirtual)" "Nonpaged : $(Format-HumanReadable $memd.Nonpaged)" [Environment]::NewLine } else { $memd.PSObject.TypeNames.Insert(0,'BinaryNature.MemoryDetailed') Write-Output $memd } } else { # Create custom "core" memory object # Value in bytes for memory attributes $memb = New-Object -TypeName PSObject -Property @{ TotalPhysicalMem=$w32perf.PhysicalTotalBytes AvailPhysicalMem=$w32perf.PhysicalAvailableBytes Computer=$env:COMPUTERNAME } if ($Format) { $memb | Select-Object @{n="Name"; e={$_.Computer}}, @{n="Total"; e={Format-HumanReadable $_.TotalPhysicalMem}}, @{n="InUse"; e={Format-HumanReadable ($_.TotalPhysicalMem - ` $_.AvailPhysicalMem)}}, @{n="Avail"; e={Format-HumanReadable $_.AvailPhysicalMem}}, @{n="Use%"; e={[int]((($_.TotalPhysicalMem - ` $_.AvailPhysicalMem) / $_.TotalPhysicalMem) * 100)}} } else { $memb.PSObject.TypeNames.Insert(0,'BinaryNature.Memory') Write-Output $memb } } }

Test Environment
The following tasks provide an example of how to configure a test environment for utilization of the Get-Memory function. I included this section for those individuals that want a "quick hack" method of getting things staged for following along in the Usage section. It is required that all computers be members of an Active Directory domain for this scenario. In my test environment, all commands will be run from a management workstation except for the Configure PowerShell Remoting task which will need to be run on each computer < Windows 2012.

# Create the PowerShell script module
We will create a basic PowerShell script module by running the following commands from an elevated PowerShell prompt. In my example, the module will be named BNTools. The notepad $bnmod command will open the notepad application (to edit the BNTools.psm1 file) where you will then copy/paste/save the Get-Memory function from the above code block.

PS> New-Item -Path $pshome\Modules\BNTools\BNTools.psm1 -Type file -Force -OutVariable bnmod
PS> notepad $bnmod

# Copy the PowerShell script module to remote computers
The PowerShell script module will need to be stored on each of the remote computers we connect to. In my example, I will save it in the default system location ($PSHOME\Modules). Verify the File and Printer Sharing (SMB-In) firewall rule, for the Inbound Rules set, is enabled on each computer. I've also created a $servers variable that contains the computer names for my test environment. Run the following commands from an elevated PowerShell prompt:

PS> $servers = 'dc01','db01','exch01','sp01'
PS> $servers | % { Copy-Item -Recurse -Force -Verbose -Path $pshome\Modules\BNTools -Destination \\$_\c$\Windows\System32\WindowsPowerShell\v1.0\Modules }

# Configure PowerShell Remoting
Remember that Windows PowerShell Remoting is enabled by default for Windows Server 2012 and later (within a trusted or domain network), so you can skip this task for those members. I'm working with Windows Server 2008 R2 VMs in my test environment, so I enable PowerShell Remoting by running the following command from an elevated PowerShell prompt on each computer:

PS> Enable-PSRemoting -Force

# PowerShell Execution Policy
Now that we have PowerShell Remoting enabled, we can verify/set the execution policy for PowerShell. My example will use RemoteSigned for the value to set on each of the computers. The following commands can be run from a normal (non-elevated) PowerShell prompt, but the credential object will need to contain the credentials of an AD administrator user account.

PS> $cred = Get-Credential 'example\administrator'
PS> Invoke-Command -Credential $cred -ComputerName $servers -ScriptBlock { if ((Get-ExecutionPolicy) -ne 'RemoteSigned') { Set-ExecutionPolicy RemoteSigned -Force } }
PS> Invoke-Command -Credential $cred -ComputerName $servers -ScriptBlock { Get-ExecutionPolicy } | ft pscomp*,value -auto

PSComputerName Value
-------------- -----
exch01 RemoteSigned
dc01 RemoteSigned
db01 RemoteSigned
sp01 RemoteSigned


Usage
The Get-Memory PowerShell function emits PowerShell objects, so we have a multitude of choices for processing and output. In addition to the "raw" output of the objects, each also has a -Format option. The option formats the numbers into human-readable form. For example, 1048576 bytes becomes 1 MB. My implementation actually omits the space and B (ex. 1M).

# Default Output

PS> Import-Module BNTools
PS> Get-Memory | fl

AvailPhysicalMem : 294473728
Computer : MGMT
TotalPhysicalMem : 1073205248

PS> Get-Memory -Detailed

KernelWorkingSet : 3588096
AvailPhysicalMem : 293928960
Nonpaged : 34111488
PagedVirtual : 113336320
CacheWorkingSet : 37961728
Computer : MGMT
DriverWorkingSet : 8429568
CommitPeak : 1307279360
CommitCurrent : 955514880
TotalPhysicalMem : 1073205248
CommitLimit : 2146947072
PagedWorkingSet : 102797312


# Output with Format option
The -Format option comes with a caveat. The human-readable value is the result of a number to string data type conversion, so keep this limitation in mind when further processing (sorting, comparison, etc.) is attempted on the value.

PS> Get-Memory | gm -MemberType prop*

TypeName: BinaryNature.Memory

Name MemberType Definition
---- ---------- ----------
AvailPhysicalMem NoteProperty System.Int64 AvailPhysicalMem
Computer NoteProperty System.String Computer
TotalPhysicalMem NoteProperty System.Int64 TotalPhysicalMem

PS> Get-Memory -Format | gm -MemberType prop*

TypeName: Selected.System.Management.Automation.PSCustomObject

Name MemberType Definition
---- ---------- ----------
Avail NoteProperty System.String Avail
InUse NoteProperty System.String InUse
Name NoteProperty System.String Name
Total NoteProperty System.String Total
Use% NoteProperty System.Int32 Use%


Unless I need to perform further operations on a property of the memory object, I usually enable the -Format option for easier readability of the output. If you're a true geek and love to do mental calculations of bytes to $x, then feel free to stick with the default output. :-)

PS> Get-Memory -Format

Name : DC01
Total : 2G
InUse : 906.1M
Avail : 1.1G
Use% : 44


The following example uses PowerShell Remoting to connect to a remote server, retrieve the detailed system memory statistics, and have the information returned and displayed in formatted output:

PS> $cred = Get-Credential 'example\administrator'
PS> Invoke-Command -Credential $cred -ComputerName exch01 -ScriptBlock { ipmo bntools; Get-Memory -Detailed -Format }
-------------
Commit Charge
-------------
Current : 3.8G
Limit : 6G
Peak : 3.9G
Peak/Limit : 64.90 %
Curr/Limit : 62.72 %


---------------
Physical Memory
---------------
Total : 3G
Available : 805.6M
CacheWS : 59.6M
KernelWS : 32K
DriverWS : 6M


-------------
Kernel Memory
-------------
PagedWS : 94.3M
PagedVirt : 94.8M
Nonpaged : 37.9M


# Fan-Out Remoting (One-to-Many)
The previous examples have demonstrated interactive or one-to-one operations, but what if we need to scale out to multiple computers? This example will connect to multiple servers, return specified data, sort on usage, and display the result in a formatted table.

PS> $cred = Get-Credential 'example\administrator'
PS> $servers = 'dc01','db01','exch01','sp01'
PS> Invoke-Command -Credential $cred -ComputerName $servers -HideComputerName -ScriptBlock { ipmo bntools; Get-Memory -Format } | select * -excl run* | sort 'Use%' -Descending | ft -auto

Name Total InUse Avail Use%
---- ----- ----- ----- ----
EXCH01 3G 2.1G 911.2M 70
SP01 2G 1G 983.8M 52
DC01 2G 923M 1.1G 45
DB01 2G 772.8M 1.2G 38


What if we need a list of servers with a Kernel Working Set value greater than 1 MB?

PS> $cred = Get-Credential 'example\administrator'
PS> $servers = 'dc01','db01','exch01','sp01'
PS> Invoke-Command -Credential $cred -ComputerName $servers -ScriptBlock { ipmo bntools; Get-Memory -Detailed } | ? { $_.KernelWorkingSet -gt 1mb } | select comp*

Computer
--------
SP01
DC01
DB01


# Out-GridView
Pipe to an interactive table instead of the console?

PS> $cred = Get-Credential 'example\administrator'
PS> $servers = 'dc01','db01','exch01','sp01'
PS> Invoke-Command -Credential $cred -ComputerName $servers -HideComputerName -ScriptBlock { ipmo bntools; Get-Memory -Format } | select * -excl run* | sort 'Use%' -Descending | Out-GridView -Title 'Server Memory Stats'


# Output to CSV
An interactive table is nice, but sometimes we just need to output to the tried-and-true comma-separated values (CSV) file type.

PS> $cred = Get-Credential 'example\administrator'
PS> $servers = 'dc01','db01','exch01','sp01'
PS> Invoke-Command -Credential $cred -ComputerName $servers -HideComputerName -ScriptBlock { ipmo bntools; Get-Memory -Format } | select * -excl run*,ps* | sort Name | Export-Csv -Path $HOME\Documents\server_memory_stats.csv -NoTypeInformation


# Other Cool Output

Get-Memory + Get-DiskFree + Get-OSInfo + XHTML =

Read More
Posted in PowerShell, Windows | No comments

Thursday, 9 May 2013

Install Request Tracker 4

Posted on 21:47 by Unknown
The argument could be made Request Tracker is the de facto standard when it comes to issue tracking systems. Maybe the only drawback of RT is the slight learning curve required to deploy it. My objective for this post is to provide a sample solution that alleviates this.

The core components required for installation:
  • CentOS (or if you prefer the Ubuntu/Debian version of this tutorial)
  • MariaDB
  • Apache HTTP Server
  • Request Tracker

1. Operating System
Our solution will be using the CentOS-6.4-x86_64-minimal.iso image. The aim of this image is to install a very basic CentOS 6.4 system, with the minimum number of packages needed to have a functional system. This post won't document the install process for CentOS 6 considering each organization has different requirements. The basic stages of the OS installation consist of language, storage, hostname, network, timezone, and setting the root password.

Note: All commands are run within the context of the root user account unless otherwise specified.

# 1.1 Updates and core packages
Make sure to update the system before we get things started.
# yum update

Let's also install the following packages that are not included by default.
# yum install file ntp vim-enhanced man man-pages wget yum-utils

# 1.2 hosts file
It's recommended to add a hostname entry (FQDN and short), of the local computer, to the hosts file. You can update the entry manually (via text editor) or run the following set of commands.

# ipv4addr=$(ip -f inet addr show dev eth0 | sed -n 's/^ *inet *\([.0-9]*\).*/\1/p')
# printf "$ipv4addr\t$(hostname -f)\t$(hostname -s)\n" >> /etc/hosts
# unset -v ipv4addr

Verify the entry.

# cat /etc/hosts

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
10.1.260.43 rt.corp.example.com rt

# 1.3 SELinux
My use case doesn't require SELinux to be active, so I will disable it in my configuration. If you have a particular requirement that states SELinux be enabled, then further modification and testing (in addition to this tutorial) may be necessary to result in a successful solution. The Request Tracker Wiki SELinux page should point you in the right direction.
# vim /etc/sysconfig/selinux

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of these two values:
# targeted - Targeted processes are protected,
# mls - Multi Level Security protection.
SELINUXTYPE=targeted

Reboot the computer for the change to take effect. After logging in after the reboot, verify SELinux is disabled.
# sestatus
SELinux status: disabled

# 1.4 Network Time Protocol (NTP)
Time synchronization is an often overlooked, but a very essential, configuration step for new server deployments. In my configuration, I will have my request tracker server sync with an Active Directory domain controller (which holds the PDC emulator FSMO role) on my private network. We will need to modify the ntp.conf file with a text editor and start the NTP daemon (and also set it for autostart at boot time). Notice that I "comment out" the default public pool.ntp.org virtual cluster servers. You may want to leave these enabled if you don't have a particular time source to sync with.
# vim /etc/ntp.conf


...
# Permit all access over the loopback interface. This could
# be tightened as well, but to do so would effect some of
# the administrative functions.
restrict 127.0.0.1
restrict -6 ::1

# Hosts on local network are less restricted.
#restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap

# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
#server 0.centos.pool.ntp.org
#server 1.centos.pool.ntp.org
#server 2.centos.pool.ntp.org


# Use internal NTP Server (AD/DC01)
server 10.1.260.11 iburst


#broadcast 192.168.1.255 autokey # broadcast server
#broadcastclient # broadcast client
#broadcast 224.0.1.1 autokey # multicast server
#multicastclient 224.0.1.1 # multicast client
#manycastserver 239.255.254.254 # manycast server
#manycastclient 239.255.254.254 autokey # manycast client
...

Start the NTP daemon.

# service ntpd start
Starting ntpd: [ OK ]

Set NTP daemon for autostart at boot time and verify.

# chkconfig ntpd on; chkconfig --list ntpd
ntpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off

We can verify the NTP status by running the following commands:

# ntpq -pn
remote refid st t when poll reach delay offset jitter
==============================================================================
*10.1.260.11 50.23.135.154 3 u 50 64 37 0.892 11.750 3.961


# ntpstat
synchronised to NTP server (10.1.260.11) at stratum 4
time correct to within 125 ms
polling server every 512 s

# 1.5 Firewall
We need to add firewall rules to open both the Hypertext Transfer Protocol (HTTP) and Hypertext Transfer Protocol Secure (HTTPS) ports for communication between our server and external users. Take note the HTTP port will only service as a redirect to HTTPS.
# vim /etc/sysconfig/iptables

# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT

-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

Restart the firewall service for the change to take effect.
# service iptables restart
iptables: Flushing firewall rules: [ OK ]
iptables: Setting chains to policy ACCEPT: filter [ OK ]
iptables: Unloading modules: [ OK ]
iptables: Applying firewall rules: [ OK ]

# 1.6 Extra Packages for Enterprise Linux (EPEL)
Our solution will require the inclusion of the EPEL YUM repository for the mod_fcgid package. Visit the EPEL site to verify you grab the latest version of the epel-release RPM package file. At the date of this post, the following command will download and install the RPM package:
# yum install http://ftp.osuosl.org/pub/fedora-epel/6/i386/epel-release-6-8.noarch.rpm

Let's verify the EPEL repository is enabled.
# yum repolist
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
epel/metalink | 9.0 kB 00:00
* base: mirrors.syringanetworks.net
* epel: mirrors.syringanetworks.net
* extras: ftp.osuosl.org
* updates: linux.mirrors.es.net
epel | 3.9 kB 00:00
epel/primary_db | 5.1 MB 00:00
repo id repo name status
base CentOS-6 - Base 6,381
epel Extra Packages for Enterprise Linux 6 - x86_64 8,754
extras CentOS-6 - Extras 12
updates CentOS-6 - Updates 647
vmware-tools VMware Tools 43
repolist: 15,837

If the repository is not enabled, you can run the following command to enable it:
# yum-config-manager --enable epel

2. Database
Our solution will use MariaDB for the RT data store. MariaDB is an enhanced, drop-in replacement for MySQL. Visit the MariaDB site for more information.

# 2.1 MariaDB package repository
Let's first add the MariaDB repo to our local YUM configuration.
# cat >> /etc/yum.repos.d/MariaDB.repo << EOF
> [mariadb]
> name = MariaDB
> baseurl = http://yum.mariadb.org/5.5/centos6-amd64
> gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
> gpgcheck=1
> EOF

Verify.
# cat /etc/yum.repos.d/MariaDB.repo
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/5.5/centos6-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

Then also verify the repository is enabled.
# yum repolist
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.syringanetworks.net
* epel: mirror.pnl.gov
* extras: ftp.osuosl.org
* updates: linux.mirrors.es.net
mariadb | 1.9 kB 00:00
mariadb/primary_db | 15 kB 00:00
repo id repo name status
base CentOS-6 - Base 6,381
epel Extra Packages for Enterprise Linux 6 - x86_64 8,754
extras CentOS-6 - Extras 12
mariadb MariaDB 9
updates CentOS-6 - Updates 647
vmware-tools VMware Tools 43
repolist: 15,846

# 2.2 MariaDB install
Install the MariaDB components.
# yum install MariaDB-server MariaDB-client MariaDB-devel

# 2.3 MySQL (MariaDB) daemon
Start the MySQL daemon.
# service mysql start

Verify the MySQL daemon is set for autostart at boot.
# chkconfig --list mysql
mysql 0:off 1:off 2:on 3:on 4:on 5:on 6:off

3. Web Server
We will be using the tried-and-true Apache HTTP Server as the web server component for our solution.

# 3.1 Download and install
Download and install httpd and other RT dependency packages.
# yum install httpd httpd-devel mod_ssl mod_fcgid make gcc openssl-devel gd-devel perl-CPAN perl-YAML perl-GD graphviz-perl

# 3.2 httpd daemon
Start the httpd daemon.
# service httpd start

Set the httpd daemon for autostart at boot.
# chkconfig httpd on

4. Request Tracker (RT)
We are now at the stage of the process to get Request Tracker installed with a base configuration.

# 4.1 Users and group
Create the rt system account user and user private group (UPG).
# useradd -r -s /sbin/nologin rt

Add the apache user to the rt group.
# usermod -aG rt apache

# 4.2 Stage RT build environment
Download the latest RT 4 compressed tarball, unpack and navigate into the directory.
# cd
# wget http://download.bestpractical.com/pub/rt/release/rt.tar.gz
# tar xf rt.tar.gz -C /tmp
# cd /tmp/rt-*

# 4.3 RT Configure script
We will be running the configure script with a number of default and explicit options. Since we haven't defined it otherwise, our default install path location will be /opt/rt4.
# ./configure --with-web-user=apache --with-web-group=apache --enable-graphviz --enable-gd

# 4.4 Perl CPAN.pm
The installation of RT requires we enter the Perl CPAN.pm shell before running the RT dependency checker. Within the shell, let's set the configuration to automate the majority of the module installs.
# cpan
...
Would you like me to configure as much as possible automatically? [yes] <enter>
...
cpan[1]> o conf prerequisites_policy follow
cpan[2]> o conf build_requires_install_policy yes
cpan[3]> o conf commit
cpan[4]> q

# 4.5 RT Perl dependencies
For the few times you may be prompted for an install, select the default choice. Iterate the make fixdeps command until you reach the output statement All dependencies have been found.
# make testdeps
# make fixdeps

Verify.
# make testdeps
/usr/bin/perl ./sbin/rt-test-dependencies --verbose --with-mysql --with-fastcgi
perl:
>=5.8.3(5.10.1) ...found
users:
rt group (rt) ...found
bin owner (root) ...found
libs owner (root) ...found
libs group (bin) ...found
web owner (apache) ...found
web group (apache) ...found
CLI dependencies:
Term::ReadKey ...found
Getopt::Long >= 2.24 ...found
HTTP::Request::Common ...found
Term::ReadLine ...found
Text::ParseWords ...found
LWP ...found
CORE dependencies:
DateTime >= 0.44 ...found
Class::ReturnValue >= 0.40 ...found
Text::Quoted >= 2.02 ...found
Regexp::IPv6 ...found
HTML::TreeBuilder ...found
CSS::Squish >= 0.06 ...found
Encode >= 2.39 ...found
DateTime::Locale >= 0.40 ...found
Module::Versions::Report >= 1.05 ...found
MIME::Entity >= 5.425 ...found
Digest::SHA ...found
List::MoreUtils ...found
DBI >= 1.37 ...found
Locale::Maketext::Lexicon >= 0.32 ...found
Devel::StackTrace >= 1.19 ...found
Digest::base ...found
HTML::FormatText ...found
Text::Password::Pronounceable ...found
Devel::GlobalDestruction ...found
Time::ParseDate ...found
File::Temp >= 0.19 ...found
Locale::Maketext >= 1.06 ...found
Tree::Simple >= 1.04 ...found
Text::Template >= 1.44 ...found
Scalar::Util ...found
HTML::Quoted ...found
HTML::Scrubber >= 0.08 ...found
File::Spec >= 0.8 ...found
DBIx::SearchBuilder >= 1.59 ...found
Sys::Syslog >= 0.16 ...found
Mail::Mailer >= 1.57 ...found
File::ShareDir ...found
Regexp::Common ...found
Digest::MD5 >= 2.27 ...found
Cache::Simple::TimedExpiry ...found
File::Glob ...found
Class::Accessor >= 0.34 ...found
Locale::Maketext::Fuzzy ...found
Time::HiRes ...found
Text::Wrapper ...found
Regexp::Common::net::CIDR ...found
Net::CIDR ...found
Log::Dispatch >= 2.23 ...found
UNIVERSAL::require ...found
Email::Address ...found
DASHBOARDS dependencies:
HTML::RewriteAttributes >= 0.05 ...found
URI >= 1.59 ...found
MIME::Types ...found
FASTCGI dependencies:
FCGI::ProcManager ...found
FCGI >= 0.74 ...found
GD dependencies:
GD::Text ...found
GD ...found
GD::Graph ...found
GPG dependencies:
PerlIO::eol ...found
GnuPG::Interface ...found
GRAPHVIZ dependencies:
IPC::Run >= 0.90 ...found
GraphViz ...found
ICAL dependencies:
Data::ICal ...found
MAILGATE dependencies:
Pod::Usage ...found
Getopt::Long ...found
LWP::UserAgent ...found
MASON dependencies:
Storable >= 2.08 ...found
CSS::Squish >= 0.06 ...found
Apache::Session >= 1.53 ...found
Errno ...found
Devel::StackTrace >= 1.19 ...found
IPC::Run3 ...found
CGI::Cookie >= 1.20 ...found
Text::WikiFormat >= 0.76 ...found
XML::RSS >= 1.05 ...found
HTML::Mason >= 1.43 ...found
Digest::MD5 >= 2.27 ...found
JSON ...found
MYSQL dependencies:
DBD::mysql >= 2.1018 ...found
PSGI dependencies:
CGI::Emulate::PSGI ...found
CGI >= 3.38 ...found
CGI::PSGI >= 0.12 ...found
HTML::Mason::PSGIHandler >= 0.52 ...found
Plack >= 0.9971 ...found
Plack::Handler::Starlet ...found
SMTP dependencies:
Net::SMTP ...found
USERLOGO dependencies:
Convert::Color ...found

All dependencies have been found.

# 4.6 Install RT and initialize RT database
After we have verified the Perl dependencies for RT have been met, we can start the install.
# make install
...
Congratulations. RT is now installed.


You must now configure RT by editing /opt/rt4/etc/RT_SiteConfig.pm.

(You will definitely need to set RT's database password in
/opt/rt4/etc/RT_SiteConfig.pm before continuing. Not doing so could be
very dangerous. Note that you do not have to manually add a
database user or set up a database for RT. These actions will be
taken care of in the next step.)

After that, you need to initialize RT's database by running
'make initialize-database'

Let's now run the following command to create the RT database and user. We haven't set the MySQL root password yet, so it will be "blank" by default.
# make initialize-database
/usr/bin/perl -I/opt/rt4/local/lib -I/opt/rt4/lib sbin/rt-setup-database --action init --prompt-for-dba-password
In order to create or update your RT database, this script needs to connect to your mysql instance on localhost as root
Please specify that user's database password below. If the user has no database
password, just press return.

Password: <enter>
Working with:
Type: mysql
Host: localhost
Name: rt4
User: rt_user
DBA: root
max_allowed_packet is set to 1.0M, which limits the maximum attachment or email size that RT can process. Consider adjusting MySQL's max_allowed_packet setting.
Now creating a mysql database rt4 for RT.
Done.
Now populating database schema.
Done.
Now inserting database ACLs.
Granting access to rt_user@'localhost' on rt4.
Done.
Now inserting RT core system objects.
Done.
Now inserting data.
Done inserting data.
Done.

# 4.7 Configure Apache for RT
Set HTTP to HTTPS redirect for all incoming HTTP requests.

# cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.orig
# vim /etc/httpd/conf/httpd.conf


...
#
# VirtualHost example:
# Almost any Apache directive may go into a VirtualHost container.
# The first VirtualHost section is used for requests without a known
# server name.
#
#<VirtualHost *:80>
# ServerAdmin webmaster@dummy-host.example.com
# DocumentRoot /www/docs/dummy-host.example.com
# ServerName dummy-host.example.com
# ErrorLog logs/dummy-host.example.com-error_log
# CustomLog logs/dummy-host.example.com-access_log common
#</VirtualHost>
<VirtualHost *:80>
ServerName rt.corp.example.com:80
Redirect / https://rt.corp.example.com/
</VirtualHost>


The install of the mod_ssl module created a default configuration file (ssl.conf). We will be leveraging this file for our RT configuration.

# cp /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf.orig
# vim /etc/httpd/conf.d/ssl.conf


...
# Per-Server Logging:
# The home of a custom SSL log file. Use this when you want a
# compact non-error SSL logfile on a virtual host basis.
CustomLog logs/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

# Request Tracker
ServerName rt.corp.example.com:443
AddDefaultCharset UTF-8
DocumentRoot /opt/rt4/share/html
Alias /NoAuth/images/ /opt/rt4/share/html/NoAuth/images/
ScriptAlias / /opt/rt4/sbin/rt-server.fcgi/
<Location />
Order allow,deny
Allow from all
</Location>
<Directory "/opt/rt4/sbin">
SSLOptions +StdEnvVars
</Directory>


</VirtualHost>

Verify the Apache configuration.

# service httpd configtest
Syntax OK

# 4.8 RT_SiteConfig.pm file
Request Tracker is very customizable, but the following base configuration settings should get you started.
# vim /opt/rt4/etc/RT_SiteConfig.pm

...
# You must restart your webserver after making changes to this file.

Set( $rtname, 'example.com');
Set( $Organization, 'corp.example.com');
Set( $Timezone, 'US/Pacific');
Set( $WebDomain, 'rt.corp.example.com');
Set( $WebPort, 443);
Set( $WebPath, '');


# You must install Plugins on your own, this is only an example
...

Restart the httpd daemon.
# service httpd restart

# 4.9 Moment of truth
Open a web browser and enter http://rt.corp.example.com (or https://rt.corp.example.com) into the web address field, then press the enter key to establish a secure connection to the RT server. If everything has been installed and configured correctly, you should be presented with the RT Login page.

The default administrative credentials are:
  • Username: root
  • Password: password


5. Post-Install
At this point, we should have a basic RT server up and running, but we need to perform some additional post-install tasks for Request Tracker, and its components, in the areas of security and functionality.

# 5.1 MariaDB
You may remember from the previous steps we never set a password for the default MySQL root user account. The mysql_secure_installation command will perform this task in addition to other MySQL security-related tasks.
# mysql_secure_installation

We also need to set a password for the RT database user (rt_user). The task requires that we add the password to the RT configuration and also set it in MySQL.

Add the $DatabasePassword key and corresponding value in the RT_SiteConfig.pm file.
# vim /opt/rt4/etc/RT_SiteConfig.pm

...

Set( $rtname, 'example.com');
Set( $Organization, 'corp.example.com');
Set( $Timezone, 'US/Pacific');
Set( $WebDomain, 'rt.corp.example.com');
Set( $WebPort, 443);
Set( $WebPath, '');
Set( $DatabasePassword, 'Pa$$w0rD!');

...

And now in MySQL.
# mysql -u root -p
Enter password: <your_root_password>
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 5.5.30-MariaDB MariaDB Server

Copyright (c) 2000, 2013, Oracle, Monty Program Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> SET PASSWORD FOR 'rt_user'@'localhost' = PASSWORD('Pa$$w0rD!');
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> \q

I also recommend increasing the maximum values for the following MySQL parameters.
# vim /etc/my.cnf.d/server.cnf

...
# this is read by the standalone daemon and embedded servers
[server]

# this is only for the mysqld standalone daemon
[mysqld]
max_allowed_packet=16M
innodb_buffer_pool_size=256M


# this is only for embedded server
[embedded]
...

Restart the MySQL daemon.
# service mysql restart

Restart the httpd daemon.
# service httpd restart

# 5.2 mod_fcgid
As per RT documentation:

WARNING: Before mod_fcgid 2.3.6, the maximum request size was 1GB. Starting in 2.3.6, this is now 128Kb. This is unlikely to be large enough for any RT install that handles attachments.
# vim /etc/httpd/conf.d/fcgid.conf

...
# Sane place to put sockets and shared memory file
FcgidIPCDir /var/run/mod_fcgid
FcgidProcessTableFile /var/run/mod_fcgid/fcgid_shm

# Request Tracker
FcgidMaxRequestLen 1073741824


Restart the httpd daemon.
# service httpd restart

Read More
Posted in Apache, Linux, MariaDB, RT | No comments
Newer Posts Older Posts Home
Subscribe to: Comments (Atom)

Popular Posts

  • Cisco ASA SSL VPN with Active Directory
    There is little doubt the bring-your-own-device (BYOD) strategy is becoming a popular method to access company resources. As technical prof...
  • PowerShell Function for Windows System Memory Statistics
    Memory is one of the four primary hardware resources an operating system manages. The other three are cpu, disk, and network. Analysis of sy...
  • Integrate VMware Fusion with GNS3 on your Mac
    At long last, we can finally integrate VMware Fusion with GNS3. VMware Workstation for Windows and Linux has had this capability for quite s...
  • Configure Inter-VLAN routing on a Cisco L3 Catalyst Switch
    I recently had to configure inter-VLAN routing at a client's site. I don't have to perform this task on a regular basis, so I figur...
  • SSL VPN configuration on Cisco ASA with AnyConnect VPN client
    This post will describe how to setup a Cisco Adaptive Security Appliance (ASA) device to perform remote access SSL VPN with the stand-alone ...
  • Enable sudo for RHEL and CentOS
    Sudo is an arguably safer alternative to logging in (or using the su command) to the root account. Sudo allows you to partition and delegat...
  • Get Exchange Server Version and Update Info with PowerShell
    I prefer not to "reinvent the wheel", so I spent quite a bit of time searching the web for available code that would perform the t...
  • Cisco Security Device Manager on the Mac
    Cisco Router and Security Device Manager (SDM) is a Web-based device-management tool that enables you to deploy and manage the services on a...
  • Install Request Tracker 4 on Ubuntu Server
    The CentOS6/RT4 blog post has generated terrific feedback, so I figure an Ubuntu (and Debian) distribution port is essential. The core com...
  • Install Request Tracker 4
    The argument could be made Request Tracker is the de facto standard when it comes to issue tracking systems. Maybe the only drawback of RT ...

Categories

  • AD
  • Apache
  • AWS
  • Cisco
  • Exchange
  • FFmpeg
  • GNS3
  • Linux
  • Mac
  • MariaDB
  • MySQL
  • PowerShell
  • RT
  • Security
  • SSH
  • VMware
  • Windows
  • Zenoss

Blog Archive

  • ▼  2013 (8)
    • ▼  October (1)
      • Install Request Tracker 4 on Ubuntu Server
    • ►  September (1)
      • Integrate VMware Fusion with GNS3 on your Mac
    • ►  August (1)
      • PowerShell Function for Windows System Memory Stat...
    • ►  May (1)
      • Install Request Tracker 4
    • ►  April (1)
    • ►  March (1)
    • ►  February (1)
    • ►  January (1)
  • ►  2012 (3)
    • ►  December (1)
    • ►  November (1)
    • ►  April (1)
  • ►  2011 (3)
    • ►  June (1)
    • ►  May (2)
  • ►  2010 (8)
    • ►  August (1)
    • ►  July (1)
    • ►  June (1)
    • ►  May (1)
    • ►  April (1)
    • ►  March (1)
    • ►  February (1)
    • ►  January (1)
  • ►  2009 (3)
    • ►  December (1)
    • ►  November (1)
    • ►  October (1)
Powered by Blogger.

About Me

Unknown
View my complete profile