There are a couple of steps:
1 - Give your LAN host a static IP.
2 - Set up NAT to handle the port forwarding
3 - Set up ZBF rules to allow the traffic
1 - Static IP
You can either manually configure the client or use a DHCP reserved address.
DHCP reservation is a royal pain on the Cisco 800 series, make sure there are no existing bindings when you try to configure it (show ip dhcp bindings), the basic configuration is:
ip dhcp pool MATT_PC
host 192.168.0.10 255.255.255.0
client-identifier 01aa.aabb.bbcc.cc
client-name Matt-PC
host 192.168.0.10 255.255.255.0
client-identifier 01aa.aabb.bbcc.cc
client-name Matt-PC
The client-identifier is the VLAN ID prepended to the MAC address. If that fails then you can try using "hardware-address aaaa.bbbb.cccc", strangely for my dual boot system Linux only picks up the reserved address using hardware-address config and Windows 7 only works using the client-identifier option. Use whatever works!
2 - NAT forwarding
You need several bits of information, the name of the external interface, the static IP used internally, the port and protocol (TCP/UDP) that you wish to forward. The format is:
ip nat inside source static <protocol> <LAN-IP> <port> interface <external-interface> <port>
e.g. a DSL router using Dialer0 interface to forward UDP traffic on port 88 to 192.168.0.10 is:
ip nat inside source static udp 88 192.168.0.10 interface dialer0 88
3 - Set up ZBF rules to allow the traffic
This is the actual Zone Based bit. You'll need to understand the setup to tweak it, no simple guides I'm afraid.
You need to know the name of your zones, I'm using the default setup which has called the outside/internet "out-zone" and internal/LAN "in-zone". It will show up in the interface configuration under the "zone-member security XXXX" option (e.g. found with "show run interface dialer0")
You basically make a policy, then apply that policy to traffic going between two zones.
You can use CBAC with the "inspect
3a) Set up the ACL
I'm doing XBL so I need UDP/88, UDP/3074 and TCP/3074:
ip access-list extended GFW_Incoming
permit udp any host 192.168.0.10 eq 88
permit tcp any host 192.168.0.10 eq 3074
permit udp any host 192.168.0.10 eq 3074
permit udp any host 192.168.0.10 eq 88
permit tcp any host 192.168.0.10 eq 3074
permit udp any host 192.168.0.10 eq 3074
3b) Set up a class-map to match the ACL
class-map type inspect match-any Incoming-Traffic
match access-group name GFW_Incoming
match access-group name GFW_Incoming
3c) Create a policy saying what to do to the traffic
policy-map type inspect incoming-policy
class type inspect Incoming-Traffic
pass
class class-default
drop
class type inspect Incoming-Traffic
pass
class class-default
drop
Note that "pass" means let it through. Inspect means run CBAC on it, but it must be a recognised protocol. "Drop" should be clear enough, you could include "drop log" but it will never log anything (see note * at end).
3d) Tell ZBF where the policy applies, specifically between which zones.
zone-pair security Outside-to-Inside source out-zone destination in-zone
service-policy type inspect incoming-policy
service-policy type inspect incoming-policy
And that should be it!
To help troubleshoot, you can do show ip access-list GFW_Incoming and see if any packets are being matched.
Final note - why drop log doesn't log anything in this case.
ZBF creates a firewall policy for traffic going between two zones. In this case our policy is for traffic going between the out-zone (WAN) and the in-zone (LAN). The traffic is "routed" between those zones by the NAT rules doing the actual port forwarding.
Traffic that comes from the internet (out-zone) and hits the firewall without triggering a NAT rule is not going anywhere near the in-zone. The relevant policy would be out-zone to self-zone (the router itself).
So the only time our out-zone to in-zone policy can ever drop traffic is if the NAT rules are forwarding but our policy does not match (the ACL in this example), i.e. if it's configured wrong! If you want to log dropped traffic then you need to specify a policy for out-zone to self-zone and use logging on that.