Sharing (tunneling) Samba/CIFS/SMB file systems over SSH
Without disabling local file sharing
by Edwin Olson
Last verified on 1/1/2007.
Introduction
Suppose you have a samba server on server S, and wish to connect to it from a machine C. Perhaps you can't connect directly, because either S can't open port 139, or because you don't trust the security of windows file sharing. (Both are good reasons!)
Cast of characters:
- S: The samba server you want to connect to. In my case, a linux machine running samba.
- C: The client machine from which you want to access S. In my case, a Windows XP machine.
The "simple" solution is to disable file sharing on system C and ssh to S, forwarding port 139 via the ssh connection. Then you can connect to your remote samba share by connecting to "\\localhost". You must disable local file sharing, otherwise it will use port 139, making it impossible for you to tunnel another machine to that port. Unfortunately, Windows will not let you specify a port number for an SMB server; it always uses port 139. So forwarding a remote smb server to a local port other than 139 doesn't get you anywhere. Grumble!
The goal of this page is to help you access files on S from machine C without disabling file sharing on C. The same technique can be used (albeit tediously) to mount an arbitrary number of remote file systems via ssh.
Briefly, our approach is to add virtual network adapters to machine C, so that machine C can have more than one port 139. Our real interface will continue to have local file sharing running, but each virtual interface can be used as the end of an ssh tunnel. For example, we can create a virtual ethernet adapter with a IP address of 10.0.0.1, and forward S:139 to 10.0.0.1:139. This clever idea originally comes from http://lists.samba.org/archive/samba/2004-May/085358.html. I've tried to document what worked for me, which was *slightly* different than what they suggested.
The method
We start by configuring Putty, a free ssh client that supports port forwarding. I've received a report that old versions of putty may not work, but that versions newer than 0.56 are fine.
- If you are running Windows XP SP2 you *must* install this (official) Microsoft patch: http://support.microsoft.com/?id=884020.
- Download and install Putty, a very decent and free ssh client, onto C.
- Fire up Putty on C, create a new connection to S. Make sure you can ssh from C to S before going any further.
- Configure a new SSH tunnel for the connection you created in the previous step.
- Source port=10.0.0.1:139 (the IP:port notation is wider than the text box, but it will work!)
- Destination=127.0.0.1:139 (this tells the server to connect the other end of the tunnel to the server's port 139.) Previous versions of these instructions suggested S's actual IP address, which might not work if S doesn't know its own true IP address (due to NATing, for example.)
- Click the checkbox, if present, reading "Local ports accept connections from other hosts"
- Click add, save the connection
We'll give your computer an additional (fake) IP address, and we'll port forward to that address instead of the computer's real IP. Windows XP will continue to do file sharing on the real IP address. We'll assign it an IP of 10.0.0.1 (that's what we configured putty to use above.)
- System->Control Panel->Add Hardware
- Yes, Hardware is already connected
- Add a new hardware device (at bottom of list)
- Install the hardware that I manually select
- Network adapters
- Microsoft , Microsoft Loopback Adapter
- (Go through the installation procedure.)
Now we configure the new localhost adapter.
- Open up your existing (real) ethernet adapter and write down your gateway and DNS server addresses.
- Open your new fake ethernet adapter (Network Connections) , enter a made-up IP address (I suggest 10.0.0.1, which is a privately routable address that most folk don't use.)
- Enable Client for Microsoft Networks.
- Disable File and Printer Sharing for Microsoft Networks
- Enable Interent Protocol (TCP/IP)
- Click on properties for TCP/IP.
- Enter your chosen IP address (10.0.0.1), subnet mask (255.255.255.0), and gateway and DNS information you got from your real adapter.
- Under advanced->WINS, Enable LMHosts Lookup and Disable NetBIOS over TCP/IP
- Enter 9999 for the interface metric. (Necessary?)
At this point I had to reboot; it didn't tell me to, but it wasn't working.
Now we test out our connection:
- Start->run
- type: "\\10.0.0.1".
- You should be greeted by your samba share!
When things go wrong
- Did you reboot?
- Is putty running and forwarding ports?
- Are your forwarded connections working correctly? (I set up a port forwarding on port 80 as a sanity check: if I could point mozilla at http://10.0.0.1 and get my server's web server, I know that putty/port forwarding is working.)
- Make sure your samba server is properly configured (did you add C to your hosts allow in smb.conf?)
- Try telnetting to 10.0.0.1 139 from a command shell on C. Do you get a connection? If it doesn't connect, then either samba or port forwarding is bonked.
- Using XP SP2? Make sure to check out Microsoft's knowledgebase article listed here: http://support.microsoft.com/?id=884020.
If I've missed something, give me a yell.
Hints from others:
Others have tried this and emailed me hints and troubleshooting information.
I have not verified this information, but I archive it here in the hope that
some of it may be useful to you.
Robert S writes:
I was recently unable to get this to work on a work PC - until I upgraded
PuTTY. It might be worth pointing out that this does not work with older
versions of PuTTY, even though they allow port forwarding. It certainly
works with version 0.56.
I am using PuTTY with PowerMenu, which allows you to send the PuTTY window
to the system tray. A good way of avoiding desktop clutter. You can
download it at http://www.veridicus.com/tummy/programming/powermenu.
Andrew Beck writes:
It seems that microsoft networking attempts to use directory
services over port 445. If this fails it then attempts to use port
139. Firstly you need to stop port 445 being bound by windows (google
gives options). Personally I use my firewall to block outgoing
connections on 445. It also appears that if there are no valid
interfaces with netbios over tcp enabled, then windows will not
attempt to use port 139. If you are using dialup (which doesn't have
this option) and don't have a lan connected, chances are samba over
ssh won't work.
The work around: Add a second loopback adapter with some IP address.
Enable netbios over TCP on this adapter. You never actually use this
adapter but it's presence causes windows to fall back to port 139 on
the loopback being used for ssh fowarding. It is bizarre, but it
works!
Sam Samdi writes:
Although things didn't initially work for me, the following did (and might
be worth adding to your page, if you feel it is appropriate)
With the loopback adaptor: I disabled Client for MS Networks and removed
the gateway IP from the TCP/IP setup.
With my SSH clients: Putty - for the remote machine I put the WAN/internet
IP address (127.0.0.1 didn't work).
OpenSSH (Cygwin SSH) - in the SSH config file (../home/user/.ssh/config) I
put the following lines:
LocalForward 139 wanserver:139
GatewayPorts yes
(wanserver is my server's WAN/internet IP; GatewayPorts allows the client
to tunnel from all loopback adaptors - 10.0.0.1 as well as 127.0.0.1)
Alex Yakushev and Jeremy Ano suggest increasing the "metric" for the loopback adapter so that it is
larger than your primary internet connection (9999 ought to do the
trick.) Without this, it seems all internet traffic tried to use the
loopback adapter (Windows must have assumed some bogus routing
information).
Brent Gerig has an idea for an alternative approach: the whole procedure of creating a
loopback adapter might be unnecessary, since any address of the format
127.0.0.x is automatically a loopback address (more rigorously,
localhost is 127.0.0.0/8). The notion is that you could forward the
samba connection from, for example, 127.0.0.2. I wasn't able to get
this to work though; it seemed to me that windows built-in networking
binds to all these addresses simultaneously (and so 127.0.0.2:139
becomes an alias for localhost:139).
|