Sorting SSH from SCP for QoS

When you’re configuring QoS on a low bandwidth link, you separate out your low-latency traffic and prioritise it over your bulk traffic, so your voice, video, DNS etc isn’t impacted by large data transfers. Easy enough.

A typical configuration might look something like this, on the average Cisco router:

ip access-list extended ssh
 permit tcp any eq 22 any
 permit tcp any any eq 22

class-map match-any lowdelay
 match ip dscp ef
 match access-group name ssh
 ! ...a few other things here

policy-map voice_qos
 class lowdelay
  priority level 1
  ! Restrict prioritised traffic to about 70% of the 10M link bandwidth
  police cir 7000000
   violate-action drop
 class class-default
  fair-queue
  random-detect

interface GigabitEthernet0/0
 ! ...
 service-policy output voice_qos

interface GigabitEthernet0/1
 ! ...
 service-policy output voice_qos

(the fact that there’s no such thing as an ‘average’ Cisco router when it comes to QoS, and the general disaster that is Cisco’s QoS implementation is a rant for a whole other post)

Anyway. The class-map defines the services that are prioritised – in most cases you want to include SSH for administration, things tagged DSCP expedited-forwarding (ie. your VOIP RTP traffic), and typically a few other things I’ve stripped from the example for clarity.

The problem with this is that SCP traffic, rsync-over-SSH etc will get lumped in with your low latency class. This means that when your backups kick off, or someone starts SCPing an ISO somewhere your VOIP and SSH traffic starts getting dropped. Dropping SSH from the low latency class is one answer, but a bit of a pain when you’re trying to work out why everything’s suddenly gone slow.

SSH is supposed to tag interactive traffic as DSCP 0x04 / TOS 0x10, but unfortunately this seems to have been broken at some point and was fixed with the IPQoS config option in OpenSSH 5.7. The new default doesn’t seem to reliably set a DSCP value, at least on the traffic I can capture here, and if you don’t control all your SSH servers there’s not much to can do to change this.

The obvious-in-retrospect fix, thanks to this ServerFault post, is to filter based on packet size. Interactive traffic will have smaller packets than large file transfers (which will use the largest possible packet size, so 1500 bytes less any encapsulation you have on your network).

Is this obvious? I dunno, I thought it was nifty ;) Here’s the config – as the ServerFault post mentions, you may need to tune the packet size to suit your environment:

ip access-list extended ssh
 permit tcp any eq 22 any
 permit tcp any any eq 22

class-map match-all ssh-interactive
 match access-group name ssh
 match packet length max 600

class-map match-any lowdelay
 match ip dscp ef
 match class-map ssh-interactive
 ! ...a few other things here

policy-map voice_qos
 class lowdelay
  priority level 1
  ! Restrict prioritised traffic to about 70% of the 10M link bandwidth
  police cir 7000000
   violate-action drop
 class class-default
  fair-queue
  random-detect

interface GigabitEthernet0/0
 ! ...
 service-policy output voice_qos

interface GigabitEthernet0/1
 ! ...
 service-policy output voice_qos
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s