Mike's Technology and Finance Blog covers a number of different topics in finance and technology. Most technical posts provide architecture, development, implementation, troubleshooting techniques for different Enterprise IT systems that run on the Windows, UNIX, and Linux platforms. Some posts also include my personal opinions and rants.
Wednesday, February 27, 2013
HyperTerminal Alternatives for Windows 8 and Windows Server 2012
In previous posts, I covered how to obtain HyperTerminal for Windows 7, Windows Server 2008 R2, Windows 8, and Windows Server 2012 using an installation of Windows Server 2003 or Windows XP. Not everyone still has copies of these outdated operating systems and it might be time to move on to newer serial console software. In this post, I provide a few alternatives to using Hyperterminal.
Wednesday, February 13, 2013
Gateway-to-Gateway IPSec Encryption on Cisco IOS
Strong encryption is the most important important aspect to ensuring data confidentiality when it is in transit across a network. Various protocols for transport level encryption exist. A couple of the more commonly cited ones are Secure Sockets Layer (SSL)/Transport Layer Security (TLS) and IP Security (IPSec).
SSL and TLS are common for websites, file transfers, and other application level services while IPSec is typically used to encrypt all traffic (or potentially a subset) between two or more endpoints (node-node IPSec), two or more gateways (gateway-gateway IPSec), and between oner or more nodes and one or more gateways (node-gateway IPSec).
In this example, I will configure IPSec encryption between two "trusted" networks over a network that is "untrusted." Assume that we have the following topology:
To begin, we need a plan...
Traffic originating from 192.168.1.0/24 and traveling across T1's fa0/0 interface to 192.168.2.0 should be encrypted. Traffic from 192.168.2.0/24 to 192.168.1.0/24 should also be encrypted (note that it is possible to encrypt asymmetrically, but not recommended). In this case, we are looking for security over performance, so we will use AES encryption (vs 3DES or DES, which are considered weak).
To begin, let's configure suitable policies on T1 and T2:
! Define a new internet security association key management protocol (ISAKMP) policy
crypto isakmp policy 1
! Use AES encryption
encryption aes
! Define pre-shared keys, as opposed to certificate based authentication/exchange
authentication pre-share
! Diffie-Hellman group 2 - more secure than group 1, but also more CPU intensive
group 2
! Specify the key lifetime (time until renegotiation)
lifetime 600
! Define a shared key for encrypting traffic between T1 and T2. Use password 'mypasswd'
crypto isakmp key mypasswd address 1.1.1.6
Now for the configuration on T2 (similar to T1, but with different peer address):
!
crypto isakmp policy 1
encryption aes
authentication pre-share
group 2
lifetime 600
crypto isakmp key mypasswd address 1.1.1.2
!
Now, we want to define the transform set. For the c3725 Series routers running IOS 12.4, we can define up to three transforms + compression. In this case, we'll define an authentication header (AH) and the AES ESP.
On T1:
crypto ipsec transform-set T2 ah-sha-hmac esp-aes
On T2:
crypto ipsec transform-set T1 ah-sha-hmac esp-aes
Note that using AH without ESP does not encrypt the packet, where it is possible to encrypt the packet using ESP without using the authentication header (AH). Combining AH and ESP encapsulates and encrypts the entire packet as we can see from the packet capture further below.
After we have the ISAKMP Policy and the transform set defined, we want to define ACLs and a crypto map that define which traffic flows need to be encrypted. The crypto map entries are fairly straightforward, defining the peer address for encryption/decryption, the transform set do be used, and the extended ACLs that define which traffic should be encrypted.
Below are the extended ACLs for matching traffic to be encrypted:
On T1:
! Match traffic originating from 192.168.1.0/24 going to 192.168.2.0/24
access-list 101 permit ip 192.168.1.0 0.0.0.255 192.168.2.0 0.0.0.255
On T2:
! Match traffic originating from 192.168.2.0/24 going to 192.168.1.0/24
access-list 101 permit ip 192.168.2.0 0.0.0.255 192.168.1.0 0.0.0.255
And now for the specific crypto map entries:
On T1:
crypto map T2 10 ipsec-isakmp
set peer 1.1.1.6
set transform-set T2
match address 101
On T2:
crypto map T1 10 ipsec-isakmp
set peer 1.1.1.2
set transform-set T1
match address 101
Now we have all of the pieces in place for IPsec. We now need to assign the crypto map to the outgoing interfaces.
On T1:
!
interface FastEthernet0/0
ip address 1.1.1.2 255.255.255.252
duplex auto
speed auto
crypto map T2
!
On T2:
!
interface FastEthernet0/0
ip address 1.1.1.6 255.255.255.252
duplex auto
speed auto
crypto map T1
!
To verify the setup, we can send packets that need to be encrypted (in this case using the IOS extended ping utility). The first ping may time out because of the security association negotiation that needs to occur:
T1#ping 192.168.2.1 source Lo0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.2.1, timeout is 2 seconds:
Packet sent with a source address of 192.168.1.1
.!!!!
Success rate is 80 percent (4/5), round-trip min/avg/max = 104/105/108 ms
We now look at whether we have an SA:
T1#show crypto isakmp sa
IPv4 Crypto ISAKMP SA
dst src state conn-id slot status
1.1.1.6 1.1.1.2 QM_IDLE 1007 0 ACTIVE
T1#show crypto isakmp sa detail
Codes: C - IKE configuration mode, D - Dead Peer Detection
K - Keepalives, N - NAT-traversal
X - IKE Extended Authentication
psk - Preshared key, rsig - RSA signature
renc - RSA encryption
IPv4 Crypto ISAKMP SA
C-id Local Remote I-VRF Status Encr Hash Auth DH Lifetime Cap.
1007 1.1.1.2 1.1.1.6 ACTIVE aes sha psk 2 00:07:21
Engine-id:Conn-id = SW:7
And we can perform further verification with a packet capture that shows encapsulated/encrypted traffic:
See Also:
The Road to the CCIE
SSL and TLS are common for websites, file transfers, and other application level services while IPSec is typically used to encrypt all traffic (or potentially a subset) between two or more endpoints (node-node IPSec), two or more gateways (gateway-gateway IPSec), and between oner or more nodes and one or more gateways (node-gateway IPSec).
In this example, I will configure IPSec encryption between two "trusted" networks over a network that is "untrusted." Assume that we have the following topology:
To begin, we need a plan...
Traffic originating from 192.168.1.0/24 and traveling across T1's fa0/0 interface to 192.168.2.0 should be encrypted. Traffic from 192.168.2.0/24 to 192.168.1.0/24 should also be encrypted (note that it is possible to encrypt asymmetrically, but not recommended). In this case, we are looking for security over performance, so we will use AES encryption (vs 3DES or DES, which are considered weak).
To begin, let's configure suitable policies on T1 and T2:
! Define a new internet security association key management protocol (ISAKMP) policy
crypto isakmp policy 1
! Use AES encryption
encryption aes
! Define pre-shared keys, as opposed to certificate based authentication/exchange
authentication pre-share
! Diffie-Hellman group 2 - more secure than group 1, but also more CPU intensive
group 2
! Specify the key lifetime (time until renegotiation)
lifetime 600
! Define a shared key for encrypting traffic between T1 and T2. Use password 'mypasswd'
crypto isakmp key mypasswd address 1.1.1.6
Now for the configuration on T2 (similar to T1, but with different peer address):
!
crypto isakmp policy 1
encryption aes
authentication pre-share
group 2
lifetime 600
crypto isakmp key mypasswd address 1.1.1.2
!
Now, we want to define the transform set. For the c3725 Series routers running IOS 12.4, we can define up to three transforms + compression. In this case, we'll define an authentication header (AH) and the AES ESP.
On T1:
crypto ipsec transform-set T2 ah-sha-hmac esp-aes
On T2:
crypto ipsec transform-set T1 ah-sha-hmac esp-aes
Note that using AH without ESP does not encrypt the packet, where it is possible to encrypt the packet using ESP without using the authentication header (AH). Combining AH and ESP encapsulates and encrypts the entire packet as we can see from the packet capture further below.
After we have the ISAKMP Policy and the transform set defined, we want to define ACLs and a crypto map that define which traffic flows need to be encrypted. The crypto map entries are fairly straightforward, defining the peer address for encryption/decryption, the transform set do be used, and the extended ACLs that define which traffic should be encrypted.
Below are the extended ACLs for matching traffic to be encrypted:
On T1:
! Match traffic originating from 192.168.1.0/24 going to 192.168.2.0/24
access-list 101 permit ip 192.168.1.0 0.0.0.255 192.168.2.0 0.0.0.255
On T2:
! Match traffic originating from 192.168.2.0/24 going to 192.168.1.0/24
access-list 101 permit ip 192.168.2.0 0.0.0.255 192.168.1.0 0.0.0.255
And now for the specific crypto map entries:
On T1:
crypto map T2 10 ipsec-isakmp
set peer 1.1.1.6
set transform-set T2
match address 101
On T2:
crypto map T1 10 ipsec-isakmp
set peer 1.1.1.2
set transform-set T1
match address 101
Now we have all of the pieces in place for IPsec. We now need to assign the crypto map to the outgoing interfaces.
On T1:
!
interface FastEthernet0/0
ip address 1.1.1.2 255.255.255.252
duplex auto
speed auto
crypto map T2
!
On T2:
!
interface FastEthernet0/0
ip address 1.1.1.6 255.255.255.252
duplex auto
speed auto
crypto map T1
!
To verify the setup, we can send packets that need to be encrypted (in this case using the IOS extended ping utility). The first ping may time out because of the security association negotiation that needs to occur:
T1#ping 192.168.2.1 source Lo0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.2.1, timeout is 2 seconds:
Packet sent with a source address of 192.168.1.1
.!!!!
Success rate is 80 percent (4/5), round-trip min/avg/max = 104/105/108 ms
We now look at whether we have an SA:
T1#show crypto isakmp sa
IPv4 Crypto ISAKMP SA
dst src state conn-id slot status
1.1.1.6 1.1.1.2 QM_IDLE 1007 0 ACTIVE
T1#show crypto isakmp sa detail
Codes: C - IKE configuration mode, D - Dead Peer Detection
K - Keepalives, N - NAT-traversal
X - IKE Extended Authentication
psk - Preshared key, rsig - RSA signature
renc - RSA encryption
IPv4 Crypto ISAKMP SA
C-id Local Remote I-VRF Status Encr Hash Auth DH Lifetime Cap.
1007 1.1.1.2 1.1.1.6 ACTIVE aes sha psk 2 00:07:21
Engine-id:Conn-id = SW:7
And we can perform further verification with a packet capture that shows encapsulated/encrypted traffic:
See Also:
The Road to the CCIE
Tuesday, February 5, 2013
Candlestick and OHLC Charting With .Net Charting Library
The .Net Framework's most recent versions (4 and 4.5) come with a fairly useful charting library for developing Windows Forms applications. It is really easy to put together a charting application using the System.Windows.Forms.DataVisualization.Charting namespace and the .Net Chart class.
Most of the chart types are fairly straightforward, but the financial chart types (point and figure, candlestick, and OHLC) are a little less intuitive because they require multiple Y values per DataPoint and Microsoft has done a poor job documenting the right order to add these. I suppose that this post could fill that gap.
For the OHLC and Cadlestick chart types, the right order to add the open, high, low, and close values to a DataPoint is the following: high, low, close, open. See the following code sample where I plot a set of trading day values for a particular equity:
} -->
In the end, you get a correct Candlestick Chart (in my case, I'm building an application to help my trading skills):
Most of the chart types are fairly straightforward, but the financial chart types (point and figure, candlestick, and OHLC) are a little less intuitive because they require multiple Y values per DataPoint and Microsoft has done a poor job documenting the right order to add these. I suppose that this post could fill that gap.
For the OHLC and Cadlestick chart types, the right order to add the open, high, low, and close values to a DataPoint is the following: high, low, close, open. See the following code sample where I plot a set of trading day values for a particular equity:
private void RefreshChart()
{
//Clear the points that are currently plotted
CandlestickChart.Series["OHLCSeries"].Points.Clear();
//Plot a subset of points from our time series
for (int i = start_i; i <= end_i; i++)
{
CandlestickChart.Series["OHLCSeries"].Points.AddY(
current_equity[i].high,
current_equity[i].low,
current_equity[i].close,
current_equity[i].open);
}
In the end, you get a correct Candlestick Chart (in my case, I'm building an application to help my trading skills):
Monday, February 4, 2013
How to Obtain Windows Hardware Information
In many support scenarios, it is necessary to obtain information on the loaded drivers and hardware for a system. This information can be dumped using the msinfo32 utility found on every current supported version of the Windows Operating System.
For Windows Vista, Windows 7, Windows Server 2008, and Windows Server 2008 R2, this tool can be ran from the "search" bar on the start menu:
For the most recent Windows OD (Windows 8 and Windows Server 2012), use the search functionality by pointing the mouse (or tapping) to the top right corner of the screen and clicking search:
Inside of the tool, click File -> Save and save the system information to the file. The saved file can then be uploaded/emailed to the person providing support.
For Windows Vista, Windows 7, Windows Server 2008, and Windows Server 2008 R2, this tool can be ran from the "search" bar on the start menu:
For the most recent Windows OD (Windows 8 and Windows Server 2012), use the search functionality by pointing the mouse (or tapping) to the top right corner of the screen and clicking search:
Inside of the tool, click File -> Save and save the system information to the file. The saved file can then be uploaded/emailed to the person providing support.
Friday, February 1, 2013
Advanced Sorting in .Net Using Comparison and IComparer
In my last post I covered some of the basics with using IComparer and Comparison for sorting collections in .Net that implement the Sort() method. In this post, we will take a look at some more advanced sorting scenarios where multi-level sorting needs to be used.
First, what is multi-level sorting?
Multi-level sorting requires sorting each record of a set by more than one parameter. Each successive parameter in the sort is used if the preceding parameters are equal. Take the following example showing 5 unsorted first and last names:
Now, let's say we want this example to be sorted by last name (first parameter) and then by first name (second parameter).
For Benjamin Franklin and George Washington, the second sort parameter (first name) doesn't matter because there are no other people with the last names Washington or Franklin in the set. For John and Jane, the second sort parameter matters because they have the same last name.
Now on to an applied example from the world of finance... Let's take an example where we have a set of investment positions (both long and short) across commodities, foreign exchange (forex), and the equities (stock) markets. We'll start out with the following basic definitions:
--> -->
Now, we'll define a problem where we have a number of investment positions that we want to sort by dollar-value gain/loss and within each gain/loss category we want to order by description (note that I've artificially set up the prices to have a few instances of equal gains/losses so that we end up sorting on the Description field). The reason why I included the InvestmentType enumeration in this example is because gain/loss is calculated differently for foreign exchange than it is for most other investments and we'll end up needing to take this into account. How to calculate the gain or loss on a foreign exchange position or a typical asset is below:
Like my previous example, we will start out by creating a new unit test and create some investment positions.
Then add them to the List<T> that we are going to sort...
Now we define a sort order (first on dollar value gain, then on description) and sort them...
//First parameter of sort operation - Gain/Loss
And check if they end up in the right order...
First, what is multi-level sorting?
Multi-level sorting requires sorting each record of a set by more than one parameter. Each successive parameter in the sort is used if the preceding parameters are equal. Take the following example showing 5 unsorted first and last names:
First Name | Last Name |
John | Smith |
Jane | Smith |
Benjamin | Franklin |
George | Washington |
Now, let's say we want this example to be sorted by last name (first parameter) and then by first name (second parameter).
First Name | Last Name |
Benjamin | Franklin |
Jane | Smith |
John | Smith |
George | Washington |
For Benjamin Franklin and George Washington, the second sort parameter (first name) doesn't matter because there are no other people with the last names Washington or Franklin in the set. For John and Jane, the second sort parameter matters because they have the same last name.
Now on to an applied example from the world of finance... Let's take an example where we have a set of investment positions (both long and short) across commodities, foreign exchange (forex), and the equities (stock) markets. We'll start out with the following basic definitions:
public enum PositionType
{
/// <summary>
/// A long position is generally taken when an asset
/// is expected to increase in value. An investor would
/// profit by buying an asset (stock, bond, foreign currency,
/// mutual fund, exchange traded fund (ETF), commodity futures
/// contract, equity option, etc.) at a low price and then
/// selling it at a higher price at some time in the future
/// </summary>
Long,
/// <summary>
/// A short position is generally taken when an asset
/// is expected to decrease in value. An investor would
/// profit by borrowing and selling an asset (stock, bond,
/// foreign currency, mutual fund, exchange traded fund (ETF),
/// commodity futures contract, equity option, etc.) at a high price
/// and then buying it back at a lower price at some time in the future
/// </summary>
Short
}
public enum InvestmentType
{
Bond,
Commodity,
Private_Equity,
Foreign_Exchange,
Public_Equity,
Mutual_Fund,
Equity_Option,
Other_Derivative
}
public class InvestmentPosition
{
public InvestmentType InvestmentType;
public PositionType PositionType;
public string Description;
public int Quantity;
public decimal Initial_Price;
public decimal Final_Price;
} -->Now, we'll define a problem where we have a number of investment positions that we want to sort by dollar-value gain/loss and within each gain/loss category we want to order by description (note that I've artificially set up the prices to have a few instances of equal gains/losses so that we end up sorting on the Description field). The reason why I included the InvestmentType enumeration in this example is because gain/loss is calculated differently for foreign exchange than it is for most other investments and we'll end up needing to take this into account. How to calculate the gain or loss on a foreign exchange position or a typical asset is below:
Foreign Exchange Trades | Most Other Investments |
Like my previous example, we will start out by creating a new unit test and create some investment positions.
[TestMethod]
public void TestSort_DollarValue_Description()
{
InvestmentPosition i1 = new InvestmentPosition()
{
InvestmentType = BlogExamples.InvestmentType.Public_Equity,
PositionType = BlogExamples.PositionType.Short,
Description = "Equity - Apple (AAPL) - Short",
// Gain of $20,000
Initial_Price = 700,
Final_Price = 500,
Quantity = 100
};
InvestmentPosition i2 = new InvestmentPosition()
{
InvestmentType = BlogExamples.InvestmentType.Public_Equity,
PositionType = BlogExamples.PositionType.Short,
Description = "Equity - Facebook (FB) - Short",
// Gain of $20,000
Initial_Price = 30,
Final_Price = 20,
Quantity = 2000
};
InvestmentPosition i3 = new InvestmentPosition()
{
InvestmentType = BlogExamples.InvestmentType.Public_Equity,
PositionType = BlogExamples.PositionType.Long,
Description = "Equity - Microsoft (MSFT) - Long",
//Gain of 1000
Initial_Price = 25,
Final_Price = 30,
Quantity = 200
};
InvestmentPosition i4 = new InvestmentPosition()
{
InvestmentType = BlogExamples.InvestmentType.Foreign_Exchange,
PositionType = BlogExamples.PositionType.Short,
Description = "Forex - EUR/USD - Short",
//Gain of 100 PIPS ~ $48.31 gain
Initial_Price = 1.3500m,
Final_Price = 1.3400m,
Quantity = 10000
};
InvestmentPosition i5 = new InvestmentPosition()
{
InvestmentType = BlogExamples.InvestmentType.Foreign_Exchange,
PositionType = BlogExamples.PositionType.Long,
Description = "Forex - AUD/USD - Long",
//Loss of 25 PIPS ~ $24.10 loss
Initial_Price = 1.0400M,
Final_Price = 1.0375M,
Quantity = 10000
};
-->Then add them to the List<T> that we are going to sort...
List<InvestmentPosition> objects = new List<InvestmentPosition>();
objects.AddRange(new InvestmentPosition[] { i5, i1, i4, i3, i2 });
-->Now we define a sort order (first on dollar value gain, then on description) and sort them...
objects.Sort((x, y) =>
{
int ret = -1;
//First, what are the gains and losses?
//Normally, this would probably be encapsulated in the investment class,
//but I put it in the sort function instead...
decimal gain_x =
x.InvestmentType == InvestmentType.Foreign_Exchange ?
( //Calculate foreign exchange gain or loss
x.PositionType == PositionType.Long ?
(decimal)x.Quantity * (1m - (x.Initial_Price / x.Final_Price))
: //Or for short
(decimal)x.Quantity * ((x.Initial_Price / x.Final_Price) - 1m)
) : //Otherwise, calculate as a regular asset
( // Calculate gain/loss as a regular asset
x.PositionType == PositionType.Long ?
(decimal)x.Quantity * (x.Final_Price - x.Initial_Price)
: // For shorting a regular asset
(decimal)x.Quantity * (x.Initial_Price - x.Final_Price)
);
decimal gain_y =
y.InvestmentType == InvestmentType.Foreign_Exchange ?
( //Calculate foreign eychange gain or loss
y.PositionType == PositionType.Long ?
(decimal)y.Quantity * (1m - (y.Initial_Price / y.Final_Price))
: //Or for short
(decimal)y.Quantity * ((y.Initial_Price / y.Final_Price) - 1m)
) : //Otherwise, calculate as a regular asset
( // Calculate gain/loss as a regular asset
y.PositionType == PositionType.Long ?
(decimal)y.Quantity * (y.Final_Price - y.Initial_Price)
: // For shorting a regular asset
(decimal)y.Quantity * (y.Initial_Price - y.Final_Price)
);
if (gain_y > gain_x)
{
ret = 1;
}
//gain_y < gain_x case handled above with the default value of ret
else if (gain_y == gain_x)
{
//Second parameter of sort - based on description
//If the objects are not of type IComparable or
//if you need more parameters for your sort, then
//you would need to add a case for x.Description == y.Description
ret = x.Description.CompareTo(y.Description);
}
return ret;
});
-->And check if they end up in the right order...
//Correct order should be i1,i2,i3,i4,i5
Assert.AreEqual(i1, objects[0]);
Assert.AreEqual(i2, objects[1]);
Assert.AreEqual(i3, objects[2]);
Assert.AreEqual(i4, objects[3]);
Assert.AreEqual(i5, objects[4]);
Long story short, multi-level sorting breaks down to the following pattern:
public class SpecialComparison : IComparer
{
public int Compare(SomeObject x, SomeObject y)
{
//First layer of sort (using parameter1)
int ret = x.parameter1.CompareTo(y.parameter1);
if (ret == 0)
{
//Second layer of sort (using parameter2)
ret = x.parameter2.CompareTo(y.parameter2);
if (ret == 0)
{
//Third layer of sort (using parameter3)
ret = x.parameter3.CompareTo(y.parameter3);
}
}
}
}
-->
Subscribe to:
Posts (Atom)