SSH through firewalls using a reverse SSH tunnel

There are many posts on the Internet with instructions to set up SSH tunnels. However, the tutorials I found described either ways to:

  • forward HTTP and other protocols from a firewalled machine through one that is not firewalled,
  • or forward ports on the inside of the firewall (that aren’t supposed to be accessible outside of it) through an SSH tunnel to allow access from outside of the firewall.

What I didn’t find, was instructions on using SSH tunnels to allow me to SSH from a non-firewalled machine to one that is behind a firewall and NAT.

The short solution is to run sshd on the firewalled machine, and use the second method to forward the ports on localhost to a remote machine.

To do this requires setting up a reverse SSH tunnel. In short, the firewalled machine will SSH to the non-firewalled machine, and expose a port on that machine that the non-firewalled machine can SSH to. SSH’ing to the new port will create an SSH connection to the firewalled machine’s SSHD.

In my particular case, the firewalled machine was running Windows, so Cygwin was used with OpenSSH. The non-firewalled machine was running Ubuntu 11.10 Oneiric Ocelot.

Detailed instructions follow:

Install SSH

First, install Cygwin on the firewalled machine. Cygwin can be downloaded from http://www.cygwin.com/. When installing Cygwin, it will ask what packages you want to install. You will need OpenSSH, which is not enabled by default. Navigate to the package (it’s under Net) or search for it, and click the text “skip” to change it to a version number. Then click next to continue the installation.

After installing Cygwin, you may want to add Cygwin’s bin directory to your PATH. The rest of the examples in this tutorial assume you have done so.

Configure SSHD

Next you will need to configure SSHD on the firewalled machine, and start it. From Cygwin’s bash command prompt, enter the following:

ssh-host-config -y
cygrunsrv -S sshd

I followed the instructions at Noah’s SSHD HowTo to do this step. That site also provides a fix for an error that you may get. I did not get the error initially, but I reinstalled Cygwin and it came up that time. The solution on that page worked for me.

Test SSH to localhost

To ensure that SSHD is up and running on the firewalled machine, ssh to localhost from the firewalled machine’s Cygwin bash:

ssh localhost

If SSHD is working, you will be able to connect to the firewalled machine’s SSHD from the firewalled machine.

Test SSH to the non-firewalled machine

To ensure that you can connect out from the firewalled machine to the non-firewalled machine, ssh to the non-firewalled machine’s external IP:

ssh nonfirewalledmachineuser@non.firewalled.machines.external.ip

You need to be able to ssh to the non-firewalled machine in order to set up the reverse tunnel.

Set up the reverse tunnel

To set up the tunnel itself, I followed the instructions on HowToForge’s Reverse SSH Tunneling article.

From the firewalled machine’s Cygwin bash prompt, run:

ssh -R 19999:localhost:22 nonfirewalledmachineuser@non.firewalled.machines.external.ip

Where 19999 is the port to set up on the non-firewalled machine, and 22 is the port on localhost to route the connection to. If the connection ever times out, the tunnel will be broken, so you need to keep the connection alive. You can run top to keep the connection alive.

Once that is connected, you can ssh to the firewalled machine from the non-firewalled machine by running:

ssh firewalledmachineuser@localhost -p 19999

Other SSH-based services like sshfs can also be used through the tunnel. You may also want to run SSH without any standard input or commands running:

ssh -nNT -R 19999:localhost:22 nonfirewalledmachineuser@non.firewalled.machines.external.ip

or if you want to run it in the background:

ssh -fnNT -R 19999:localhost:22 nonfirewalledmachineuser@non.firewalled.machines.external.ip

These two options seem to keep alive by themselves, but I am not sure if it is guaranteed that they will. There are various keep-alive tricks described in the comments of a blog post on The Mad Philosopher. My preferred solution is to put

ServerAliveInterval 60
ServerAliveCountMax 9999

into $HOME/.ssh/config.

Posted in Uncategorized | Leave a comment

Battlezone-style weapon pickups in Unreal Engine 3

Given the vehicle class provided in the previous post, it is easy to create a pickup that can change the weapon selection for the vehicle.

To provide the simplest possible example that demonstrates the concept, this example makes the weapon pickup a subclass of Actor. It would be possible to implement the pickup as a subclass of some other base class as well, if those classes had functionality you wanted to keep. The weapon will be picked up when touched by the vehicle, so I’ve placed the pickup code inside of the class’ touch() event.

The crude version looks like this:

class CrudeWeaponChangePickup extends Actor;

var class<UTVehicleWeapon> weaponClass;

event touch(Actor other, PrimitiveComponent otherComp, vector hitLocation, vector hitNormal) {
  local WeaponChangeGoliath touchVehicle;

  touchVehicle = WeaponChangeGoliath(other);
  if (touchVehicle != none) {
    touchVehicle.toggleWeapons[touchVehicle.toggleWeaponIndex] = weaponClass;
    touchVehicle.changeWeapon(0, touchVehicle.toggleWeapons[touchVehicle.toggleWeaponIndex]);
    destroy();
  }
}

defaultproperties
{
  weaponClass=class'UTVWeap_MantaGun';
  
  Begin Object Class=SkeletalMeshComponent Name=PickupMesh ObjName=PickupMesh Archetype=SkeletalMeshComponent'UTGame.Default__UTBeamWeapon:PickupMesh'
    SkeletalMesh=SkeletalMesh'WP_RocketLauncher.Mesh.SK_WP_RocketLauncher_3P'
    ObjectArchetype=SkeletalMeshComponent'UTGame.Default__UTBeamWeapon:PickupMesh'
  End Object
  Components.Add(PickupMesh)

  Begin Object Class=CylinderComponent NAME=CollisionCylinder
    CollisionRadius=+00030.000000
    CollisionHeight=+00020.000000
    CollideActors=true
  End Object
  CollisionComponent=CollisionCylinder
  Components.Add(CollisionCylinder)

  bOnlyDirtyReplication=true
  NetUpdateFrequency=8
  RemoteRole=ROLE_SimulatedProxy
  bHidden=false
  NetPriority=+1.4
  bCollideActors=true
  bCollideWorld=true
  bOrientOnSlope=true
  bShouldBaseAtStartup=true
  bIgnoreEncroachers=false
  bIgnoreRigidBodyPawns=true
  bUpdateSimulatedPosition=true
}

Inside the touch event, it checks if the thing it touched was the WeaponChangeGoliath presented in the earlier post by attempting a typecast. If that is not null, then the thing that was touched was a WeaponChangeGoliath. In that case, the pickup changes the currently-selected weapon in the vehicle’s toggleWeapons array to the weaponClass of this pickup. In order to make the change effective, the pickup also calls the WeaponChangeGoliath’s changeWeapon method, passing the new weapon class. Once the weapon has been changed, the pickup is used up, so it destroys itself.

In Battlezone, weapons are categorized by their type, so a “Gun” type weapon can only replace another “Gun” type weapon. To support this behavior, a modified version of the WeaponChangeGoliath and WeaponChangePickup can be used:

class WeaponChangeGoliath extends UTVehicle_Goliath_Content;

var int toggleWeaponIndex;
var array< name > toggleWeaponNames;
var array< class<UTVehicleWeapon> > toggleWeapons;

exec function toggleWeapon() {
  toggleWeaponIndex++;
  if (toggleWeaponIndex >= toggleWeapons.length)
    toggleWeaponIndex -= toggleWeapons.length;
    
  changeWeapon(0, toggleWeapons[toggleWeaponIndex]);
}

simulated function switchWeapon(byte newGroup) {
  local int newWeaponIndex;
  
  newWeaponIndex = newGroup-1;
  if (newWeaponIndex >= 0 && newWeaponIndex < toggleWeapons.length && newWeaponIndex != toggleWeaponIndex) {
    toggleWeaponIndex = newWeaponIndex;
    changeWeapon(0, toggleWeapons[newWeaponIndex]);
  }
}

function changeWeapon(int seatNum, class<UTVehicleWeapon> newGunClass) {
  if (seats[seatNum].gun != none) {
    // Might be overkill on the "stop firing" stuff here.
    if (seatNum == 0)
      stopFiringWeapon();
    seats[seatNum].gun.endFire(0);
    seats[seatNum].gun.endFire(1);
    seats[seatNum].gun.forceEndFire();
    seats[seatNum].gun.destroy();
  }

  seats[seatNum].GunClass = newGunClass;
  seats[seatNum].Gun = UTVehicleWeapon(InvManager.CreateInventory(seats[seatNum].GunClass));
  seats[seatNum].Gun.SetBase(self);

  if (seats[seatNum].gun != none) {
    seats[seatNum].gun.SeatIndex = seatNum;
    seats[seatNum].gun.MyVehicle = self;
    if (seatNum == 0) {
      weapon = seats[seatNum].gun;
      invManager.setCurrentWeapon(seats[0].gun);
    }
  }
}

defaultproperties
{
  toggleWeaponIndex=0
  toggleWeapons(0)=class'UTVWeap_GoliathTurret';
  toggleWeapons(1)=class'UTVWeap_GoliathMachineGun';
  toggleWeaponNames(0)=Cannon
  toggleWeaponNames(1)=Gun
}

The only changes made to the WeaponChangeGoliath were to add the toggleWeaponNames array, which will store the “type” of each weapon.

class WeaponChangePickup extends Actor;

var name weaponType;
var class<UTVehicleWeapon> weaponClass;

event touch(Actor other, PrimitiveComponent otherComp, vector hitLocation, vector hitNormal) {
  local int i;
  local WeaponChangeGoliath touchVehicle;

  touchVehicle = WeaponChangeGoliath(other);
  if (touchVehicle != none) {
    for (i=0;i<touchVehicle.toggleWeapons.length && i< touchVehicle.toggleWeaponNames.length;i++) {
      if (touchVehicle.toggleWeaponNames[i] == weaponType && touchVehicle.toggleWeapons[i] != weaponClass) {
        touchVehicle.toggleWeapons[i] = weaponClass;
        if (touchVehicle.toggleWeaponIndex == i)
          touchVehicle.changeWeapon(0, touchVehicle.toggleWeapons[i]);
        destroy();
        return;
      }
    }
  }
}

defaultproperties
{
  weaponType=Gun
  weaponClass=class'UTVWeap_MantaGun'
  
  Begin Object Class=SkeletalMeshComponent Name=PickupMesh ObjName=PickupMesh Archetype=SkeletalMeshComponent'UTGame.Default__UTBeamWeapon:PickupMesh'
    SkeletalMesh=SkeletalMesh'WP_RocketLauncher.Mesh.SK_WP_RocketLauncher_3P'
    ObjectArchetype=SkeletalMeshComponent'UTGame.Default__UTBeamWeapon:PickupMesh'
  End Object
  Components.Add(PickupMesh)

  Begin Object Class=CylinderComponent NAME=CollisionCylinder
    CollisionRadius=+00030.000000
    CollisionHeight=+00020.000000
    CollideActors=true
  End Object
  CollisionComponent=CollisionCylinder
  Components.Add(CollisionCylinder)

  bOnlyDirtyReplication=true
  NetUpdateFrequency=8
  RemoteRole=ROLE_SimulatedProxy
  bHidden=false
  NetPriority=+1.4
  bCollideActors=true
  bCollideWorld=true
  bOrientOnSlope=true
  bShouldBaseAtStartup=true
  bIgnoreEncroachers=false
  bIgnoreRigidBodyPawns=true
  bUpdateSimulatedPosition=true
}

For the pickup, two changes were made. First, the addition of a weaponType variable allows us to specify what type of weapon this is. Subclasses of the WeaponChangePickup can specify a different weaponType and weaponClass in their defaultproperties block, or they could be set in UnrealEd or through other Unrealscript code.

The second change is to the logic inside of the touch event. In this version, the pickup loops through all of the weapons on the vehicle, and replaces the first one with a matching weaponType that is not already this weapon type.

Posted in Uncategorized | Leave a comment

Battlezone-style weapon changes in Unreal Engine 3

In a future post, I will be providing a short tutorial on providing Battlezone-style weapon pickups for vehicles in games built using Unreal Engine 3. The existing code for vehicles in Unreal Engine 3 assumes a single weapon per vehicle “seat”, and that behaviour is not ideal for the tutorial. I have previously built a simple vehicle that can toggle between multiple weapons in the same seat, as an implementation example for the Battlezone 3 project. For reference, I’ve provided a slightly modified version of that example class here:

class WeaponChangeGoliath extends UTVehicle_Goliath_Content;

var int toggleWeaponIndex;
var array< class<UTVehicleWeapon> > toggleWeapons;

exec function toggleWeapon() {
  toggleWeaponIndex++;
  if (toggleWeaponIndex >= toggleWeapons.length)
    toggleWeaponIndex -= toggleWeapons.length;

  changeWeapon(0, toggleWeapons[toggleWeaponIndex]);
}

function changeWeapon(int seatNum, class<UTVehicleWeapon> newGunClass) {
  if (seats[seatNum].gun != none) {
    // Might be overkill on the "stop firing" stuff here.
    if (seatNum == 0)
      stopFiringWeapon();
    seats[seatNum].gun.endFire(0);
    seats[seatNum].gun.endFire(1);
    seats[seatNum].gun.forceEndFire();
    seats[seatNum].gun.destroy();
  }

  seats[seatNum].GunClass = newGunClass;
  seats[seatNum].Gun = UTVehicleWeapon(InvManager.CreateInventory(seats[seatNum].GunClass));
  seats[seatNum].Gun.SetBase(self);

  if (seats[seatNum].gun != none) {
    seats[seatNum].gun.SeatIndex = seatNum;
    seats[seatNum].gun.MyVehicle = self;
    if (seatNum == 0) {
      weapon = seats[seatNum].gun;
      invManager.setCurrentWeapon(seats[0].gun);
    }
  }
}

defaultproperties
{
  toggleWeaponIndex=0
  toggleWeapons(0)=class'UTVWeap_GoliathTurret';
  toggleWeapons(1)=class'UTVWeap_GoliathMachineGun';
  toggleWeapons(2)=class'UTVWeap_MantaGun';
}

The toggleWeapons array contains the classes of all of the weapons that we wish to toggle between. The changeWeapon function does all of the real work of changing the weapon, while the toggleWeapon exec function allows us to change the weapon from the console. toggleWeapon could also be bound to a key. If the vehicle has only one seat, and you do not need to use the number keys for anything else, you can use them to change the weapons instead. The number keys (bound to switching weapons) run through the switchWeapon method on the player’s currently controlled Pawn. We can override that method to select the weapons:

simulated function switchWeapon(byte newGroup) {
  local int newWeaponIndex;

  newWeaponIndex = newGroup-1;
  if (newWeaponIndex >= 0 && newWeaponIndex < toggleWeapons.length && newWeaponIndex != toggleWeaponIndex) {
    toggleWeaponIndex = newWeaponIndex;
    changeWeapon(0, toggleWeapons[newWeaponIndex]);
  }
}

One quick note: The switchWeapon method has not been tested in multiplayer, and probably does not work there as-is. Since it is just a convenience, and not relevant to the coming tutorial, I have not designed it for multiplayer support.

Posted in Uncategorized | 2 Comments

Developers work slower on programs that are slow

After about 10 seconds of waiting, a person’s attention begins to drift to other things. Others have written articles on the subject in the context of computer systems, but the same things has been observed by psychologists in a range of settings. If a process takes more than 10 seconds to complete, it breaks the user’s flow, and they will have to re-orient themselves once the process has finished.

The value to programmers of being in the state of flow has been noted by many authors. Programming is also an activity where a lot of automated tools are used. The tools are intended to save developer’s time, but care must be taken to ensure that the use of a tool does not break the user’s flow. If a developer is in a state of flow, and the flow is broken by a tool that takes too long to complete, the developer will lose productivity until they are able to once again enter a flow state.

The same can occur as a result of the program that the developer is working on. If the program takes a long time to compile or start up, or an operation that the developer is testing involves a long delay, the programmer’s productivity will suffer as they are constantly taken out of the flow state. Flow is also connected to happiness while doing the work, so in addition to decreased productivity, long waits during development can also harm developer’s motivation to perform well and harm the developer’s engagement with the project.

These combined factors point to a high cost to slow applications – not only do users dislike them, but developers are less productive working on them and have lower job satisfaction when doing so.

Posted in Uncategorized | Leave a comment

Strange interaction models are convenient for developers, but costly to users

Bill Slot on Self-checkout Machine

Bill Slot on Self-checkout Machine

When users want to pay cash at a self-checkout lane, the machine asks them to enter coins first, followed by bills. From the perspective of the user, this is counter-intuitive: when paying a cashier, typically the largest denominations are given first; and the machine wants the smallest denominations first.

It is common that a user wants to pay with a large bill, plus some small amount of change. If a user’s bill is, say, $9.03, and the user wishes to pay with a $10 bill, they may want to pay $10.03 instead, to get back an even dollar rather than 97 cents change.

How can the machine know whether to spit out 97 cents change or wait for the user to enter 3 additional cents? There are solutions, of varying complexity and convenience.

From a developer’s perspective, the most expedient is to accept the smallest denomination first. If users enter the smallest denomination first, they can assume that the user is finished entering money when the total entered matches or exceeds the amount owing.

There is often a trade-off between usability and development cost. In this case, the developers chose what was likely the easiest for themselves, at the expense of what was easiest to the users.

Posted in Uncategorized | Leave a comment

Self-checkout systems are slower than cashiers, especially for novices

One of the best ways to study the usability of an existing system is to watch real users using it. The techniques are most often discussed in the context of software, but usability plays a role in designing other types of systems as well.

Self-checkout system

Self-checkout system

As one example, three confederates and I observed users operating grocery-store self-checkout systems. We found that most of the users had some familiarity with the system and those users were able to operate the system quickly. Some users, who appeared to be less experienced with the devices, took longer to complete their task. These users had to carefully read each screen to figure out what to do.

The speed with which the experienced users operated the checkout system suggests it is easy for experts to use. The need to read each screen that we observed in the novice users suggests that the system is not particularly intuitive, although it probably feels intuitive to those who are already experienced with it.

We also observed that the self-checkout took longer than going through a cashier’s checkout, even for the experienced users. At least one user also commented that they preferred the human interaction with a cashier to the automated checkout system. In their current state, the main advantage of the self-checkout lane for shoppers is that the line-up is sometimes shorter.

Posted in Uncategorized | 1 Comment

Users leave websites if they can’t accomplish their task in a few minutes

A recent post by Matthew Yglesias makes mention of a common casualty of poor usability on the web.

Every day, users abandon websites when they cannot figure out how to do what they came for in a reasonable amount of time. We don’t know how long Matthew spent trying to find the information that he was looking for, but we do know (from a post by Jakob Nielsen that the average page visit lasts about 30 seconds, and more experienced users spend even less time. Most website visits last about 2-4 minutes. When users can’t accomplish the task they came for within that period of time, they will typically give up. Poor usability can prevent even a powerful website from being useful for it’s intended purpose.

Posted in Uncategorized | Leave a comment