Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I know how to use a remote CVS repository where access to the remote server is through SSH.

Here's my problem: the remote CVS server, call it "A" is accessible by SSH only from computers within the same subnet. There is one computer "B" on the subnet that has SSH open to the world. (Don't ask why; I'm not the administrator.) I can SSH into "B", and then from there SSH into "A" where the CVS repository is.

My home PC is not on the same subnet as "A" and "B". Is it possible to access the CVS repository on "A" through my SSH connections between my home PC and "B" and between "B" and "A"?

  • Without hosting another CVS repository on "B".
  • And without checking out on "B" and synchronizing my home PC with that check out.
share|improve this question
up vote 2 down vote accepted

Quack's answer is a good start, but it has two problems. Thus I'll try it too:

You first have to create a tunnel from your local workstation to the SSH port of machine A. This is easily done from the command line:

ssh -L B

(ssh to B and create a tunnel from the localport to the remote port A:22)

Because CVS doesn't allow you to specify ports when using the :ext protocol, this simple command line will not be good enough. What you need to do instead is create or modify your ~/.ssh/config file:

Host B
   LocalForward A:22

Host tunnel2a
   Port 2200

These are two entries. The first one tells ssh to create a tunnel whenever you ssh to B. The second one defines the new 'hostname' tunnel2a that you can use for cvs.

First, open the tunnel by ssh'ing to B:

ssh B

CVS should now work like that:

cvs -d :ext:username@tunnel2a:/cvsroot/ checkout someModule
share|improve this answer
terrific, manni, thx for the corrections. personally i wouldn't include that host entry for "B"; i'd name it "Btunnel" maybe and point it to "HostName B". that way i'd only get the tunnel on ssh Btunnel and not on every ssh B. otherwise +1. – quack quixote Nov 25 '09 at 15:46
Cool. I didn't know about automatically setting up tunnels through the config file. Thanks. – Posco Grubb Nov 25 '09 at 17:39

You should be able to do this through SSH tunnelling. I don't have 3 machines to test with, but if I understand the process right, you want 2 terminal windows.

In the first, SSH to "B" with this option: -L 1234:A:22. This will add a tunnel between the localhost, at port 1234, through machine "B", to machine "A", at port 22 (the SSH port).

The CVS command I originally wrote doesn't work, since CVS doesn't support ports in the :ext: format as I had written. If using a GUI IDE or CVS client, it may allow you to input an alternate port directly. If doing this with the commandline client, you'll need another route -- adding a host alias to your ~/.ssh/config file with the correct port. Manni's answer gives a great example for how that's done, so I won't reproduce that here.

By aiming at port 1234 on localhost, you'll hit the SSH tunnel and get routed to the SSH port on A.

You might want to check the answers to some related questions about SSH tunnelling. Thanks Manni for helping me beat these instructions into shape.

In the second terminal, run your CVS checkout command, but substitute localhost:1234 for A:

cvs -d :ext:username@localhost:1234:/cvs checkout test
# instead of
# cvs -d :ext:username@A:/cvs checkout test

share|improve this answer
Awesome! Thank you. I had a hunch that tunneling was part of the answer. I don't know if your cvs command is right, but I setup the tunneling and then pointed the CVS client in the Eclipse IDE to use extssh connection to localhost port 1234, and the repositories on "A" showed up. Smooth as butter! – Posco Grubb Nov 25 '09 at 7:28
This is almost right, but not quite. You don't want the new port on B where it would be accessible to the whole word. You want the port on your local workstation's localhost. ssh -L will do exactly that and thus you need to change the cvs command line because cvs needs to connect to localhost and not to B. – innaM Nov 25 '09 at 7:36
Oh. And additionally, CVS doesn't allow ports to be specified when using SSH. Duh. – innaM Nov 25 '09 at 11:01
fair points. i'd assume the B->A tunnel wouldn't bypass standard SSH security measures, so it's not horrible. but i said it wrong; my instructions do create the port on the localhost, so B:1234 really should be localhost:1234. oops. (i'll have to take your word for CVS-not-allowing-ports, since I don't use it.) – quack quixote Nov 25 '09 at 15:33
tho i did find lots of messages around the net that mention the same trouble and same solution (cvs-over-ssh via alternate port): see for example… – quack quixote Nov 25 '09 at 15:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .