CCNA Security Chapter 4 - Implementing Firewall Technologies (Part 1 ACLs)

This chapter:
Describe numbered and named, standard and extended IP ACLs.
Configure IP ACLs with IOS CLI and SDM.
Describe TCP established ACL functionality.
Configure ACLs with TCP established.
Describe and configure reflexive ACLs.
Describe and configure dynamic ACLs.
Describe and configure time-based ACLs.
Describe attack mitigation with ACLs.
Describe the major types of firewalls.
Describe and configure CBAC (IOS Stateful Packet Inspection) with CLI.
Describe and configure Zone-Based Policy Firewall with CLI and SDM.

Labs:
* Configuring CBAC and Zone-Based Firewalls, learners use CLI and CCP to configure and test Context-Based Access Control and Zone-Based Policy Firewall.

Packet Tracer activities:
* Configure IP ACLs to Mitigate Attacks - learners configure ACLs to ensure that remote access to routers is available only from management stations. Edge routers are configured with ACLs to mitigate common network attacks and these ACLs are tested for proper operation.
* Configuring Context-Based Access Control (CBAC), learners configure and IOS firewall with CBAC on a perimeter router. CBAC functionality is verified with ping, Telnet, and HTTP.
* Configuring a Zone-Based Policy Firewall (ZPF), has learners configure a ZPF policy on a perimeter router. ZPF functionality is verified with ping, Telnet and HTTP.

Download solutions for labs

Stateful firewalls use tables to track the real-time state of end-to-end sessions. Stateful firewalls take into account the session-oriented nature of network traffic.
The first stateful firewalls used the "TCP established" option for ACLs.


Debug
clear ipv6 access-list [access-list-name]
clear ipv6 inspect {session session-number | all}
clear ipv6 prefix-list [prefix-list-name] [ipv6-prefix/prefix-length
debug platform software acl config
debug platform software acl interface
debug platform software acl statistics
show platform software access-list R0 statistics
show platform software access-list R1 name OutFilter_IPv6 ace 100
show platform software access-list F0 summary


ACL - Access Control Lists
ACL defines and control classes of traffic on networking devices based on Layer 2, 3, 4, and 7 parameters of the OSI model. 
Most common types of parameters used in security-related ACLs involve IPv4 and IPv6 addresses as well as TCP and UDP port numbers.
Protocol            ACL Range
IP                  1-99, 1300-1999
Extended IP         100-199, 2000-2699
Ethernet type code  200-299
Ethernet address    700-799
* All ACLs assume an implicit deny, meaning that if a packet does not match any of the criteria specified in the ACL, the packet is denied. 
* ACE - Access Control Entries - Entries (rules) of an ACL.
* Only one ACL per interface, L3 protocol, direction at one (limitation)  
* when applying same type of ACL on the same interface, it will be overwritten.
  “ip access-group 115 in” on the s0/0/1 interface it will overwrite the initial access-list 102 "ip access-group 102 in" 
 (same interface: s0/0/1, same protocol: ip, same direction: in)

* Wildcard mask is used for filtering in ACL
* The direction of traffic through a networking device is defined by the ingress (inbound) and egress (outbound) interfaces for the traffic.
* Both standard and extended ACLs can be used to describe packets entering or exiting an interface.
* Order of statements - ACLs have a policy of first match (when a statement is matched, the list is no longer examined).
* ACLs are processed top-down
Modifying ACLs - When a router compares a packet to an ACL, the ACEs are examined from the top down. When a router locates an entry with matching criteria, the ACL processing stops and the packet is either permitted or denied based on the ACE.
When new entries are added to an ACL, they are, by default, added to the bottom of the list.
* Special packets - ACL does not block router generated traffic (to OUT).
Router-generated packets, such as routing table updates, are not subject to outbound ACL statements on the source router. If the security policy requires filtering these types of packets, inbound ACLs on adjacent routers or other router filter mechanisms using ACLs must do the filtering task.
* The any parameter is an abbreviation for the IP address of the source. Indicates a source address of 0.0.0.0 and a wildcard mask of 255.255.255.255; all source addresses will match.
* In Cisco IOS Release 12.3 and later, with the use of sequence numbers, it is possible to delete specific ACEs in standard and extended ACLs without deleting the ACL. It is also possible to add new ACEs to a specific location.
* ACL placement
Standard ACLs  - are placed close to the destination (San Diego   Standart--Destination).
Extended ACLs - are placed close to the source that is being filtered. (ESpania:  Extended--Source)
* The biggest limitation of standard and extended ACLs is that they are designed to filter unidirectional rather than bidirectional connections.
 * Note that you can apply the same ACL to multiple interfaces on a router, or you can activate the same ACL twice on the same interface: inbound and outbound.
* You can also apply a nonexistent ACL to an interface A nonexistent ACL is an ACL that has no statements in it an empty ACL will permit all traffic.
For an ACL to have an implicit deny, it needs at least one permit or deny statement It is highly recommended that you do not apply nonexistent ACLs to a router s interface.
In this situation, when you create the very first statement in the list, the implicit deny is automatically placed at the bottom, which might create reachability issues for your router.
 Let s take a look at an example that has a nonexistent ACL and examine the kinds of problems that you might experience.
 Assume that you have applied an ACL (#10) to a router s ethernet0 interface and this ACL currently doesn t have any permit or deny statements (it s empty).
 You are connected to the router via telnet on this interface, and your PC has an IP address of 192.168.1.1
You create an entry in ACL #10 that permits traffic from 172.16.0.0/16.
As soon as you do this, you lose your telnet connection. If you guessed that the implicit deny caused the router to drop your connection, you guessed correctly. As soon as the router has one statement in it, the implicit deny is added at the bottom In this example, since your PC had a source address of 19216811, and this wasn t included in the first statement, the router dropped your connection because it couldn t find any matching statements in ACL #10 A lot of confusion exists among published authors about an empty ACL: some say an empty ACL drops all traffic, some say it permits all traffic, and some say that it depends on the IOS version I ve worked with ACLs since they first came out in version 7 of the IOS, and from that version all the way up to 124T code (the latest), an empty ACL has always allowed traffic to and through the interface I encourage you to test this by applying an inbound ACL to the router s interface that has no statements and then ping that interface: the ping will work.

ACL/routing
If we have inbound ACL: Packets are processed through the access list before being routed to the outbound interface.
If we have outbound ACL: Packets are routed to the outbound interface and then processed through the access list
Yes Cisco IOS doesn't block some locally originated traffic:

Attacks that could be mitigated with ACL:  
 - IP address spoofing,
 - TCP SYN-flood attacks,
 - Reconnaissance attacks (ICMP, UDP on mgmt interface),
 - General vulnerabilities.

* ACL commands
Standart ACL command            "access-list 10 ..."
Standart Numbered ACL command   "ip access-list standard 10 <new line>  ..."
1) Standard ACLs
Standard ACLs match packets with only the source IPv4 address field in the IP header of that packet.
These ACLs are used to filter packets based solely on Layer 3 source information.
Router(config)# access-list {1-99} {permit | deny} source-addr [source-wildcard]
sample:
R1(config)# access-list 1 deny 172.16.4.0 0.0.0.255
R1(config)# access-list 1 permit any
R1(config)# interface FastEthernet 0/0
R1(config-if)# ip access-group 1 out
2) Extended ACLs
Extended ACLs match packets based on Layer 3 and Layer 4 source and destination information. Could be IP, ICMP, TCP, UDP.
Router(config)# access-list {100-199} {permit | deny} protocol source-addr [source-wildcard] [operator operand] destination-addr [destination-wildcard] [operator operand] [established]
Router(config)sample# access-list 101 deny icmp any 10.1.1.0 0.0.0.255 echo
Router(config)sample# access-list 101 permit ip any 10.1.1.0 0.0.0.255
Apply ACL on interface
The administrator must apply ACL to the appropriate interface.
Router(config-if)# ip access-group access-list-number {in | out}
Apply ACL on VTY
VTY - Virtual Terminal Line
First, VTY (Virtual Teminal Lines) are (1) of (4) main types of TTY lines used to Telnet or SSH into the router over the network. They are virtual, in the sense that they are a funtion of software - there is no hardware associated with them. The other TTY types are CTY (Console), AUX (Auxiliary), TTY (asynchronous lines used for inbound or outbound modem and terminal connections and can be seen in a router or access server configuration as line x).
 
An ACL can also be used to permit or deny specific IP addresses from gaining virtual access (vty). Standard ACLs allow restrictions to be enforced on the originator source IP address or IP address range. An extended ACL does the same but can also enforce the access protocol such as port 23 (Telnet) or port 22 (SSH).  
The access-class extended ACL only supports the "any" keyword as the destination.
The command to apply the ACL to a vty line is as follows:
Router(config-line)# access-class access-list-number {in | out}
3) Named ACL
It is possible to create a named ACL instead of a numbered ACL. Named ACLs must be specified as either standard or extended.
Named ACL starts with #ip access-list instead of #access-list for Standart and Extended ACLs
Router(config)# ip access-list [standard | extended] name_of_ACL
Router(config-std-nacl)# deny {source [source-wildcard] | any}
Router(config-std-nacl)# permit {source [source-wildcard] | any}
An extended named ACL offers additional parameters
Router(config-ext-nacl)# {permit | deny} protocol source-addr [source-wildcard] [operator operand] destination-addr [destination-mask] [operator operand] [established]
4) Activate ACL
On interface
Router(config-if)# ip access-group access-list-name {in | out}
On vty
Router(config-line)# access-class access-list-name {in | out}
5) Log ACL matches
Logging facility could be the console, the internal buffer of the router, or a syslog server.
Log messages are generated on the first packet match and then at five minute intervals after that first packet match.
Enabling the log parameter on a Cisco router or switch seriously affects the performance of that device. When logging is enabled, packets are either process- or fast-switched. 
R1(config)# access-list 101 permit tcp 192.168.1.0 0.0.0.255 192.168.2.0 0.0.0.255 eq 22 log
6) Sequence ACE in ACL
Router(config)# ip access-list standard 19
Router(config-std-nacl)# 25 permit 172.22.1.1
7) Verify ACL
Router# show access-lists
Router# show ip access-lists
Router# debug ip packet [access-list-number] [detail]
Router# show running-config
8) Advanced ACL Types
Extended IP ACLs using TCP established
The established keyword forces the router to check whether the TCP ACK or RST control flag is set. If the ACK flag is set, the TCP traffic is allowed in. If not, it is assumed that the traffic is associated with a new connection initiated from the outside.
Using the established keyword to allow return traffic into a network opens a hole in the router. Hackers can take advantage of this hole by using a packet generator or scanner, such as Nmap.
The established option does not apply to UDP or ICMP traffic, because UDP and ICMP traffic does not rely on any control flags as used with TCP traffic.
Using the established keyword does not implement a stateful firewall on a router.

" "established" only checks for the ACK bit in the TCP header.  After a three-way handshake is done, all other packets are ACK.  Not incredibly reliable, not hard to spoof.
It was really the first evolutionary step in the stateful firewall concept. It would be MUCH better to use newer things...
We went from "established" to reflexive ACLs, to CBAC (Context Based Access Controls) and now to ZBF (Zone Based Firewalls)." (link)
Router(config)# access-list {100-199} {permit | deny} protocol source-addr [source-wildcard] [operator operand] destination-addr [destination-wildcard] [operator operand] [established]
R1(config)#access-list 100 permit tcp any eq 443 192.168.1.0 0.0.0.255 established
R1(config)#access-list 100 permit tcp any 192.168.1.3 0.0.0.0 eq 22
R1(config)#interface s0/0/0
R1(config-if)#ip access-group 100 in
If the keyword established is not included, then any TCP traffic with source port 443 would be permitted.
With the keyword, only traffic from source port 443 with the ACK, FIN, PSH, RST, SYN, or URG TCP control flag set is permitted.  
Reflexive IP ACLs
Reflexive ACLs provide a truer form of session filtering than is possible with TCP established.
Source and destination addresses and port numbers are checked, not just ACK and RST bits.
Reflexive ACLs allow an administrator to perform actual session filtering for any type of IP traffic.
Reflexive ACLs work by using temporary ACEs inserted into an extended ACL, which is applied on the external interface of the perimeter router.
1. internal reflexive ACL
R1(config)# ip access-list extended internal_ACL
R1(config-ext-nacl)# permit tcp any any eq 80 reflect web-only-reflexive-ACL
R1(config-ext-nacl)# permit udp any any eq 53 reflect dns-only-reflexive-ACL timeout 10
2. out reflexive ACL
R1(config)# ip access-list extended external_ACL
R1(config-ext-nacl)#evaluate web-only-reflexive-ACL
R1(config-ext-nacl)#evaluate dns-only-reflexive-ACL
R1(config-ext-nacl)#deny ip any any
3. Apply to interface
R1(config)# interface s0/0/0
R1(config-if)# description connection to the ISP.
R1(config-if)# ip access-group internal_ACL out
R1(config-if)# ip access-group external_ACL in
Dynamic ACLs (aka Lock-and-Key ACLs)
Dynamic ACLs are available for IP traffic only.
This feature is dependent on Telnet, authentication (local or remote), and extended ACLs.
Reasons to use dynamic ACLs:
 - provide a specific remote user or group of remote users access to a host within the network.
 - when a subset of hosts on a local network needs to access a host on a remote network that is protected by a firewall.
Dynamic ACL security benefits over standart and extended ACLs:
 - Use of a challange machanims to authenticate individual users,
 - Simplified management in large internetworks,
 - In many cases, reduction of  the amount of routers processing that is rewuired for ACLs,
 - Reduction of the opprotunity for network break-ins by network hackers,
 - Creation of dynamic user access through a firewall, without compromising other configured security restrictions.

Reflexive ACL permit traverse through router only ather passing authentication (vty) .

Lock and key configuration:
1) Starts with the application of an extended ACL to block traffic through the router. 

2) Users that want to traverse the router are blocked by the extended ACL until they Telnet to the router and are authenticated.
3) The Telnet connection then drops and a single-entry dynamic ACL is added to the extended ACL that exists.
4) This permits traffic for a particular time period; idle and absolute timeouts are possible.

Router(config)# access-list {100-199} dynamic dynamic_ACL_name [timeout minutes] {permit | deny} protocol source-addr [source-wildcard] [operator operand] destination-addr [destination-wildcard] [operator operand] [established]
Two timeouts are associated with dynamic ACL entries:
 - absolute (is specified in the dynamic ACL entry)
 - idle (s specified in the autocommand command, which enables lock-and-key authentication on the vty lines)
If timeouts are not specified, the default is to never time out the entry.
Sample config
username test password 0 test
!--- Ten (minutes) is the idle timeout.
username test autocommand access-enable host timeout 10
access-list 101 permit tcp any host 10.1.1.1 eq telnet
!--- 15 (minutes) is the absolute timeout.
access-list 101 dynamic testlist timeout 15 permit ip 10.1.1.0 0.0.0.255 172.16.1.0 0.0.0.255
interface Ethernet0/0
  ip address 10.1.1.1 255.255.255.0
  ip access-group 101 in
line vty 0 4
login local
!  After the user at 10.1.1.2 makes a Telnet connection to 10.1.1.1, the dynamic ACL is applied.
The connection is then dropped, and the user can go to the 172.16.1.x network.
Therefore, it is recommended that an idle or an absolute timeout be configured.
Router(config)# line vty 0 4
Router(config-line)# autocommand access-enable host [timeout minutes]
The host parameter is optional. By specifying this parameter, the Cisco IOS replaces the dynamic ACL entry's keyword any with the user's IP address.

Time-Based ACLs
Timed-based ACLs enable traffic to be restricted based on the time of day, the day of the week, or the day of the month.
Router(config)# time-range time_range_name
Router(config-time-range)# absolute [start_time start_date] [end_time end_date]
Router(config-time-range)# periodic day_of_the_week hh:mm to [day_of_the_week] hh:mm
!
The absolute command specifies a single time period for which the time range is valid.
The periodic command specifies a recurring time period for which the time range is valid.
Sample
R1(config)# time-range employee-time
R1(config-time-range)# periodic weekdays 12:00 to 13:00
R1(config-time-range)# periodic weekdays 17:00 to 19:00
R1(config-time-range)# exit
R1(config)# access-list 100 permit ip 192.168.1.0 0.0.0.255 any time-range employee-time
R1(config)# access-list 100 deny ip any any
R1(config)# interface FastEthernet 0/1
R1(config-if)# ip access-group 100 in
R1(config-if)# exit
ACL to filter invalid source addresses
Any local host addresses (127.0.0.0/8)
Any reserved private addresses (RFC 1918, Address Allocation for Private Internets)
Any addresses in the IP multicast address range (224.0.0.0/4)
ICMP recommendations 
In this example, any ICMP echo or echo-reply traffic will be allowed until it exceeds 16K, at which point it will be dropped.
Router(config)# access-list 131 permit icmp any any echo
Router(config)# access-list 131 permit icmp any any echo-reply
Router(config)# interface eth0/0
Router(config-if)# rate-limit output access-group 131 16000 8000 8000 conform-action continue exceed-action drop
Allow ICMP types on Inbound
Type 0 — Echo Reply - Allows users to ping external hosts.
Type 3 Unreachable (have multiple codes) - Unreachable messages are generated for packets that are administratively denied by an ACL.
Type 4 — Source Quench (Deprecated) - Requests the sender to decrease the traffic rate of messages.
Allow ICMP types on Out
Type 8 — Echo (Echo request) - Allows users to ping external hosts.
Type 12 — Parameter problem - Informs the host of packet header problems.
Type 3 (destination unreachable), code 4 (fragmentation needed but don't-fragment bit set) Packet too big - Required for packet maximum transmission unit (MTU) discovery.
Type 4 — Source quench - Throttles down traffic when necessary.
As a rule, block all other ICMP message types outbound.

IPv6 ACLs
* Many network administrators are unaware that IPv6 is enabled on most operating systems.
* Dual-stacked hosts can configure themselves, and may be subject to rogue router advertisements (RAs).
* Can exploit routing header (RH) to pivot using multiple hops.
* Can exploit automatic tunnels to pivot unnoticed by firewalls and IPS.

The standard ACL functionality in IPv6 is similar to standard ACLs in IPv4.
1.Create IPv6 ACL
Router(config)# ipv6 access-list access-list-name
2.Create rules
Router(config-ipv6-acl)# {permit | deny} protocol {source-ipv6-prefix/prefix-length | any | host source-ipv6-address | auth} [operator [port-number]] {destination-ipv6-prefix/prefix-length | any | host destination-ipv6-address | auth} [operator [port-number]]
3.Activates the ACL on an interface with the ipv6 traffic-filter command
Router(config-if)# ipv6 traffic-filter access-list-name {in | out}
Each IPv6 ACL by default includes:
 - allow in/out rules to enable IPv6 neighbor discovery. The IPv6 neighbor discovery process makes use of the IPv6 Network Layer service.
 - deny all other services not specifically permitted.

 ACL fot IPv6 can filter on IPv6 extension headers.

 There is an implicit deny at the end of the access list, with the exception of neigh-bor solicitation (NS) and neighbor advertisement (NA) packets. NS and NA packets are implicitly allowed.
(Note that if including an explicit   deny you should explicitly permit these (NS and NA), before your deny if IPv6 is to function properly.)  

 If an empty access list (and access lists without any entries, which is really just a name) is applied to an interface as a filtering access list, it will not deny any traffic.
This is the exact same behavior as IPv4 packet-filtering access lists.

IPv4 => IPv6
R7(config)#ipv6 access-list PERMIT-http
R7(config-ipv6-acl)#permit tcp any any eq 80
R7(config-ipv6-acl)#deny ip any any log
Automatic is transformed to:
!
ipv6 access-list PERMIT-http
 permit tcp any any eq www
 deny ipv6 any any log
!



These ACEs allow for IPv6 neighbor discovery traffic
permit icmp any any nd-na
permit icmp any any nd-ns
deny ipv6 any any
IPv6 Neighbor Discovery Protocol (NDP)
The most distinct characteristics of IPv6 after its increased address space are its plug-and-play features.
Neighbor Discovery Protocol (NDP) is the enabler of these plug-and-play features, using the following functions:
Router Discovery -  A node can discover, when it is connected to an IPv6 link, the local routers without the aid of Dynamic Host Configuration Protocol (DHCP).
Prefix Discovery - A node can discover, when it is connected to an IPv6 link, the prefix or prefixes assigned to that link.
Parameter Discovery - A node can discover parameters such as the link MTU and hop limits for its connected link.
Address Autoconfiguration - A node can determine its full address, again without the aid of DHCP.
Address Resolution -  A node can discover the link-layer addresses of other nodes on the link without the use of Address Resolution Protocol (ARP).
Next-Hop Determination - A node on a link can determine the link-layer next hop for a destination, either as a local destination or a router to the destination.
Neighbor Unreachability Detection - A node can determine when a neighbor on a link, either another host or a router, is no longer reachable.
Duplicate Address Detection - A node can determine if an address it wants to use is already being used by another node on the link.
Redirect - A router can notify a host of a better next-hop than itself to an off-link destination. The redirect function is a part of basic ICMP functionality in IPv4, but is redefined as part of NDP in IPv6.

NDP messages should always be link-local in scope, and therefore the packets encapsulating them always
use either link-local IPv6 addresses or multicast addresses with a link-local scope.
To add a further layer of security, the Hop Limit of the IPv6 packet carrying all NDP messages is 255.
If one of these packets is received with a Hop Limit less than that value,
it means the packet has passed through at least one router, and the packet is dropped.
This prevents NDP from being attacked or spoofed from a source not attached to the local link.

NDP Messages
NDP is defined in RFC 2461. It uses ICMPv6 to exchange the messages necessary for its functions; specifically, five new ICMPv6 messages are specified in RFC 2461:

Router Advertisement (RA) messages are originated by routers to advertise their presence and link-specific parameters such as link prefixes, link MTU, and hop limits. These messages are sent periodically, and also in response to Router Solicitation messages.
Router Solicitation (RS) messages are originated by hosts to request that a router send an RA.
Neighbor Solicitation (NS) messages are originated by nodes to request another node's link layer address and also for functions such as duplicate address detection and neighbor unreachability detection.
Neighbor Advertisement (NA) messages are sent in response to NS messages. If a node changes its link-layer address, it can send an unsolicited NA to advertise the new address.
Redirect messages are used the same way that redirects are used in ICMP for IPv4; they have merely been moved from being a part of the base ICMPv6 protocol to being a part of NDP.
If you do intend on locking down the ICMP IPv6 traffic, see RFC 4890,   ICMPv6 Filtering Recommendations . 

IPv6 ACL Example
R1(config)# ipv6 access-list BOGUS_SOURCE_FILTER
R1(config-ipv6-acl)# deny 2001:12::/64 any
R1(config-ipv6-acl)# permit any any
R1(config)# int g0/3
R1(config-if)# ipv6 traffic-filter BOGUS_SOURCE_FILTER in
R1# show ipv6 access-list
IPv6 access list BOGUS_SOURCE_FILTER
    deny ipv6 2001:12::/64 any sequence 10
    permit ipv6 any any (12 matches) sequence 20 

Object groups
The Object Groups for ACLs feature lets you classify users, devices, or protocols into groups and apply those groups to access control lists (ACLs) to create access control policies for those groups

* Object groups must have unique names.
* Additional objects can be appended to existing object groups.
* Objects such as hosts, protocols, or services can be grouped.
* You cannot delete an object group or make an object group empty if it is being used in an ACE.

Network Object Groups
Router(config)# object-group network nw_grp_id
Router(config-network-group)# description description-text | host {host-address | host-name} | network-address {/prefix-length | network-mask} | range host-address1 host-address2 | any | group-object nested-object-group-name
Service Object Groups
Router(config)# object-group service svc_grp_id
Router(config-service-group)# protocol | [tcp | udp | tcp-udp [source {{[eq]| lt | gt} port1 | range port1 port2}] [{[eq]| lt | gt} port1 | range port1 port2]] | icmp icmp-type
IPv4 ACL
Router(config)# ip access-list extended name_of_ACL
Router(config-ext-nacl)# [line line_number] {permit | deny} {protocol | object-group protocol_obj_grp_id} {source-prefix/wildcard-mask | any | host source-address | object-group network_obj_grp_id} [operator {port [port]} | object-group service_obj_grp_id}] {destination-prefix/wildcard mask | any | host destination-address | object-group network_obj_grp_id} [operator {port [port] | object-group service_obj_grp_id}] {[log [level]]}
IPv6 ACL
Router(config)# ipv6 access-list access-list-name
Router(config-ipv6-acl)# {permit | deny} {protocol | object-group protocol_obj_grp_id} {source-ipv6-prefix/prefix-length | any | host source-ipv6-address | object-group network_obj_grp_id}[operator {port [port] | object-group service_obj_grp_id}] {destination-ipv6-prefix/prefix-length | any | host destination-ipv6-address | object-group network_obj_grp_id} [{operatorport [port] | object-group service_obj_grp_id}]

END OF PART 1
==============================

Link to Part 2