SSH port forwarding – as a secure proxy

I’ve built a local SSH proxy to secure traffic whilst I update this blog, so thought I would explain the syntax in some more detail than my previous post SSH Port Forwarding

The ssh utility in Linux has a feature which allows forwarding of a local port to a remote host in a number of ways. I use the -L option to forward a local port on a proxy host to a remote server, to save establishing an ssh tunnel from each machine I work from within my network.

The ssh man page explains it like this :

-L [bind_address:]port:host:hostport
Specifies that the given port on the local (client) host is to be
forwarded to the given host and port on the remote side. This
works by allocating a socket to listen to port on the local side,
optionally bound to the specified bind_address. Whenever a con-
nection is made to this port, the connection is forwarded over
the secure channel, and a connection is made to host port
hostport from the remote machine. Port forwardings can also be
specified in the configuration file. IPv6 addresses can be spec-
ified with an alternative syntax:
[bind_address/]port/host/hostport or by enclosing the address in
square brackets. Only the superuser can forward privileged
ports. By default, the local port is bound in accordance with
the GatewayPorts setting. However, an explicit bind_address may
be used to bind the connection to a specific address. The
bind_address of “localhost” indicates that the listening port be
bound for local use only, while an empty address or ‘*’ indicates
that the port should be available from all interfaces.

Simple use of the -L option as per my previous post indicates that the following command will translate a connection to a port on the localhost running ssh as a socket connection from the remote host. For example :

ssh -L 8888: [email protected]

As explained previously, this command will take a connection to port 8888 on the localhost address of my machine ( and tunnel the traffic through the ssh connection and present it from the localhost adapter on the server to the service listening on port 23, usually the telnet daemon. Worth noting, I could have forwarded port 23 on my local host, however with this being a special port I would require root access.

This method combined with autossh (to keep the tunnel live) and a small caching DNS server daemon on my LAN (DNSMasq), which points this blog to an internal IP address I can tunnel all traffic to my web server securely..

IPTables quick reference

# iptables -N new_chain                         // create a chain
# iptables -E new_chain old_chain               // edit a chain
# iptables -X old_chain                         // delete a chain

redirecting packet to a user chain:
# iptables -A INPUT -p icmp -j new_chain

listing rules:
# iptables -L                                   // list all rules of all tables
# iptables -L -v                                // display rules and their counters
# iptables -L -t nat                            // display rules for a specific tables
# iptables -L -n --line-numbers                 // listing rules with line number for all tables
# iptables -L INPUT -n --line-numbers           // listing rules with line number for specific table

manage rules:
# iptables -A chain                             // append rules to the bottom of the chain
# iptables -I chain [rulenum]                   // insert in chain as rulenum (default at the top or 1)
# iptables -R chain rulenum                     // replace rules with rules specified for the rulnum
# iptables -D chain     rulenum                 // delete rules matching rulenum (default 1)
# iptables -D chain                             // delete matching rules

change default policy:
# iptables -P chain target                      // change policy on chain to target
# iptables -P INPUT DROP                        // change INPUT table policy to DROP
# iptables -P OUTPUT DROP                       // change OUTPUT chain policy to DROP
# iptables -P FORWARD DROP                      // change FORWARD chain policy to DROP 


IPSEC – Site to site VPN

crypto isakmp policy <N> * N = priority, lower preferred

authentication pre-share
encryption <3DES/AES/DES> * AES preferred
group <1/2/5> * Diffie Hellman group
hash <MD5/SHA>
lifetime <T> * in Seconds

crypto isakmp key <0/6> <KEY> address

crypto ipsec transform-set <TRANS NAME> esp-aes esp-sha-hmac


crypto ipsec security-association lifetime <T>


crypto map <MAP NAME> <SEQ> ipsec-isakmp

match address 123
set peer <REMOTE ADDR>
set transform-set <TRANS NAME>

int dial0 <OUTSIDE IF>

crypto-map <MAP NAME>

Notes :

QM_IDLE = Good!

MM_NO_STATE = Phase 1 (*IKE problem) – Check public incoming ACL’s

MM_KEY_EXCH = Bad peer address or key problem

On public facing inbound ACL’s allow :

ESP – Protocol 50

AH – Protocol 51

IKE – UDP port 500