# [HOWTO] Tunneling the hard way: using slirp, pppd and socat

## mdeininger

I couldn't find any Howtos on doing this dirty little heretic trick so i thought I'd share how I managed to do this in form of a howto in case someone else tries doing the same -- please don't flame me too much, this is probably my first "real" howto and I know it's pretty exotic a thing to do.

Contents

1. Preface / The Problem

2. Requirements

Hardware/Equipment

Software: slirp

Software: pppd

Software: socat

3. Configuring the Client

4. Configuring the Server

5. Optional: configuring your router

6. Testing

7. The odd scenario that worked for me

8. Possible extensions

1. Preface / The Problem

Every now and then you might come across a "bad" ISP. The one I have at home for example is dropping UDP packets ever so often when I try to play online games -- and it tends to drop random packets while I try to log onto a gameserver too which makes a certain game I like to play crash during the loading phase so it can't recover. I also heard of other ISPs blocking certain ports on external servers -- universities for example seem to like blocking p2p network ports and the school i was attending till last august blocked everything but port 80 for http -- including ftp which made even on-topic "research" a pita at times.

Usually there's three ways of working around this problem if "giving up" is not an option to you: a) change your ISP, b) use ssh to redirect ports, c) connect to an external VPN to route for you. a) can be tricky -- it's impossible if you're sharing the link with your parents and they insist on their email addresses or in the university/workplace/school scenario. b) will only work with single port/host combinations and for c) you will need a full-fledged rootbox idling around on the internet -- which tend to be expensive and "virtual servers" might not work because those often don't include tun/tap devices and/or kernel-level ppp support if you rent them and in case you rented them you probably can't fiddle around with its kernel to enable it (that was my problem at least). If any of this rings a bell to you, read on and discover method d)  :Smile: 

NOTE: another application of this method is -- of course -- "anonymising". If you use this to route through a different box then you can't be traced that easily since the external box you will use in this example is effectively NATing your connection.

2. Requirements

Hardware/Equipment

As I said, this method is tricky and you do need quite some stuff to use it. You will need:

Write-access to the routing tables and clearance to add interfaces with pppd on your client box (or your router and some other internal box) -- this means you need root-level access on linux

Some external box with at least a shell account -- rootboxes are fine but a simple shell account somewhere will suffice ( yes, no root access on the host is required if you can get slirp and socat on it  :Very Happy:  )

Software: slirp

Slirp is a SLIP/PPP emulator that was originaly intended to turn dial-in shell accounts into PPP-accounts. It's in portage and you can get it at http://slirp.sourceforge.net/. You will need this on the host box.

Software: pppd

This is the PPP client we will be using. You will already have this if you use PPPoE or a Modem to connect to the internet on your client box. It's also in portage as "net-dialup/ppp" and it should be available for download at http://www.samba.org/ppp. You will need this on the client box.

Software: socat

According to it's website it's "netcat++", and I also read references to it of the form "socat is netcat on steroids" -- and that's completely true. It's the "enhanced swiss army knife" of a netadmin since you can do just about anything with it, including things like creating a wannabe-telnet server (example included in socats manpage). It's in portage and you can get it from http://www.dest-unreach.org/socat/. You will need this on both the client and the server and we will use it to establish bidirectional tcp/ip connection between the two instead of a modem.

3. Configuring the client

Okay now that we know what is needed, let's get our hands dirty. Since this is the client, you will need to install pppd and socat on this box. Also I will assume both of the boxes to use gentoo for installation instructions since I think installing those three programs -- even from source tarballs [untar; ./configure; make; make install] -- should be easy enough if you're not running gentoo. If you haven't done so already, use

```
# emerge socat ppp
```

to get the two apps.

First we will configure a pppd peer. For simplicity's sake I will call the peer "slirp". Open up nano and fill the file /etc/ppp/peers/slirp with something like this:

```
# /etc/ppp/peers/slirp

notty 115200

noauth

lcp-echo-interval 0

asyncmap 0

nodefaultroute

nodetach

```

(note: I doubt that the baudrate after the notty is actually doing something, I just left it in after experimenting, same goes for nodetach, nodefaultroute and lcp-echo-interval)

Next we will configure a handful of scripts I wrote for the tunnel connection. I made a nice configuration file at /etc/tunnel-data

```
# /etc/tunnel-data

TUNNELHOST="tunnel.host.tld"

TUNNELPORT="2198"

TUNNELIF="ppp0"

SLIRP="/usr/bin/slirp"

PPPD="/usr/sbin/pppd"

ENCAPIF="eth0"

ENCAPGW="melchior"

```

You will need to set TUNNELHOST to the your external box's hostname, TUNNELPORT to whatever you choose, TUNNELIF is the interface that will go up after you connect with ppp. It's probably ppp0 if you have an ethernet connection to your router to connect to the internet. ENCAPIF is the interface you use to connect to the internet. SLIRP and PPPD point to the application paths (I put both in this file so you can use the same configuration file on both the external host and the client. you don't need slirp on the client and you don't need pppd on the server.) ENCAPGW must point to your real gateway to the internet (your default route -- you need to set this correctly, melchior is how i called my gateway).

Now we put in all the scripts you need on the client:

fill /sbin/tunnel-up with this:

```
#!/bin/sh

. /etc/tunnel-data

route add -host $TUNNELHOST gw $ENCAPGW

socat TCP4:$TUNNELHOST:$TUNNELPORT,interface=$ENCAPIF "EXEC:$PPPD call slirp" &
```

and /sbin/tunnel-down will have to read this:

```
#!/bin/sh

. /etc/tunnel-data

route del -host $TUNNELHOST

kill `cat /var/run/$TUNNELIF.pid`
```

make both executable by issueing

```
# chmod a+x /sbin/tunnel-up /sbin/tunnel-down
```

on a shell.

add these lines to your /etc/ppp/ip-up

```
#!/bin/sh

. /etc/tunnel-data

#slirp control channel route

route add -net 10.0.2.0/24 gateway $TUNNELHOST metric 1 $TUNNELIF

#add more routes here

route add -net 213.208.119.0/24 gateway $TUNNELHOST metric 1 $TUNNELIF
```

(you can omit the #!/bin/sh if it already existed, but make sure to use chmod to make this script executable like the other two scripts if it not already is)

The line after # add more routes here is supposed to be a starting point for you to add own routes that shall go through your tunnel once it's up. The 213.208.119.0/24-network is the network of an online roleplaying game called "ryzom" that I have to route through my rootbox because of my ISPs buggy UDP routing, so i felt this might serve as an example  :Smile: 

Aight, this should do for the client part, on to the server part.

4. Configuring the Server

This one is easier. You know the drill already about the programs, install slirp and socat on the server box, for example via

```
# emerge socat slirp
```

now log into the user you will want to run slirp as and edit ~/.slirprc to read

```
ppp

asyncmap 0

#log start

#compress
```

(log start and compress should be optional, so #-ed em)

you will also need the same /etc/tunnel-data file as on the client, so copy yours from the client there (yeah you could strip it a little, that's up to you)

add the following script as /sbin/tunnel-listen

```
#!/bin/sh

. /etc/tunnel-data

socat TCP4-LISTEN:$TUNNELPORT,retry EXEC:$SLIRP &
```

and make it executable with

```
# a+x /sbin/tunnel-listen
```

okay that should do, now if you have a router and the client is "some extra box"...

5. Optional: Configuring your router

If you want everyone in your LAN to connect through the tunnel to certain sites, and they all use a gateway and that gateway is not your client and your client has routing enabled (echo 1 > /proc/sys/net/ipv4/ip_forward), you can add static routes from your router to your client. But only use static routes for everything you set up to be rerouted through the tunnel on your client in /etc/ppp/ip-up! do not make that client the default route! that's a big fat nono!

I can't exactly tell you how to do that on your router because that varies from router to router, I'm using a m0n0wall for example, and there's an option in the control menu called "static routes" that's rather self-explanatory.

6. Testing

Now the fun part: putting it all together.

on your external box run

```
# tunnel-listen
```

and on your internal client do

```
# tunnel-up
```

to see if it worked, check the output of the route command. If everything went well, it should be something like this:

```
chronos ~ # route

Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

yourtunnelhost melchior         255.255.255.255 UGH   0      0        0 eth0

yourtunnelhost *               255.255.255.255 UH    0      0        0 ppp0

10.2.0.0        *               255.255.255.0   U     0      0        0 eth0

213.208.119.0   yourtunnelhost 255.255.255.0   UG    1      0        0 ppp0

10.0.2.0        yourtunnelhost 255.255.255.0   UG    1      0        0 ppp0

loopback        *               255.0.0.0       U     0      0        0 lo

default         melchior         0.0.0.0         UG    0      0        0 eth0
```

if that seems ok, try connecting from the client to telnet://10.0.2.0, if your session looks like this:

```
telnet 10.0.2.0

Trying 10.0.2.0...

Connected to 10.0.2.0.

Escape character is '^]'.

Slirp command-line ready (type "help" for help).

Slirp>
```

everything is fine (if you have telnet that is). type quit and be happy. now set up your routes through the tunnel, or if you followed the example on ryzom and have a static route to the ryzom net from your router through the client through the tunnel to your external box, try calling the ryzom website. If set up the way I just said with a static route from router to client, calls there will only succeed if you have an active tunnel (without one, packets will bounce indefinitely between your router and the client)

NOTE that you can't traceroute and ping through the tunnel, I think it's because of slirp. IP and UDP worked for me though.

You can use tunnel-down to get the link down again (you will need to restart tunnel-listen on the server though to get it back up).

7. The odd scenario that worked for me

Okay, let's make things a little more personal. WHY did i try this in the first place? I had the problem that I couldn't play that one MMORPG (Ryzom) properly because my ISP fecked up UDP routing, and you literally can not call them without being bounced around from employee to employee for a bunch of hours, getting a lot of invalid phone and fax numbers in the process. It's virtually impossible to get a technician on the phone to tell them about issues like that, and I can't switch providers as much as I liked to, because my father insists on his email address with them. I did however have a local server box lying around, a router running m0n0wall and an external "virtual server" with root access (except for tun/tap devices, ppp or the possibility to reconfigure the kernel, so no openvpn or pptp *ugh*) so i did what i just described; my normal box is connected to the router, which lets the local server box handle routing for the ryzom net. the local server box is tunneling to the rootbox (like i just described) and that is NATing everything important to the game. Works like a charm for me, albeit i seriously wonder why  :Very Happy: 

8. Possible extensions

Socat is quite neat, especially since you could also use SSL encrypted channels instead of TCP4 channels. or UDP channels, which would be useless to me and should be odd enough, since TCP is the "safer" of the two protocols. Go read the manpages on socat for some interesting ideas  :Wink: 

----------------------------------------------

Have fun everyone!

Greetings,

Magnus

----------

## frozenJim

You have Ryzom running?!!

Please, tell me more....  What did you do to get it going?  Can a dummy like me play ryzom on my Gentoo box?

----------

## mdeininger

uhm, nothing spectacular, the first time i tried it just ran right out of the box; something broke while patching then though, so last time i gave that a shot i just followed this guide on the official forums, substituting cedega with wine:

http://www.ryzom.com/forum/showthread.php?t=8887

it's a bit slow on ati cards though, albeit it seems to run fine on my shiny new geforce... you will need more ram than on windows though  :Wink: 

aside from that i see no reason why it shouldn't work on a gentoo box, the engine actually runs on linux and the devs did a good job in making the program portable  :Smile: 

----------

## frozenJim

Oh.  That's my mistake.  I thought that there was a Linux version (now I cannot remember why I thought that).

Well, to heck with them then.  

My need to play is not so great as my need to avoid rewarding companies who shun Linux.

----------

## mdeininger

well, they originally wanted to make a Linux version, which is why they GPL'd the engine and it also compiles on Linux. They also use Debian-servers, however they didn't get around to port the actual game to Linux, because the devs were busy with the game for windows due to marketing problems (You will notice that Ryzom has a very small user-base). I'm only playing every once in a while, but I felt like supporting specifically them because they're the closest you can get to see a commercial MMORPG on anything but windows (except for WoW on OSX that is) and I found it quite nice that they GPL'd the engine.

----------

## frozenJim

Ah.  Well then, I take back my ingracious comments.

Good on'em I say!

So now it's just a matter of someone actually writing a game that utilizes the engine.  The ball is in our court.

You would think though, that they would benefit from having the Linux crowd joining up on their servers.  With the engine already written, wouldn't you think that it would be pretty straightforward for the authors to create a Linux port and then cash in on all of us starving Linux gamers?

Better for all if both Linux and Micro$oft gamers could play together on the same server.

----------

## mdeininger

that's true and I feel the same. I think there's also a petition on the official forums, but the thing is they're still working on the game's features, and something is wrong with the native linux audio drivers. It's definitely possible, but I think the game has a reputation of being a more "girly" one, and it seems the majority of users either plays on windows or doesn't have any trouble running it on wine whatsoever, except for some performance issues... If I got it right, they're also quite tight on developers, up until last month they were working on a major game enhancement, so maybe they'll look into it sometime soon  :Smile: 

----------

## frozenJim

Maybe what we need is some kind of "Linux Gaming Foundation" that is devoted to generating the money that is required for these technically challenging apps on a game-by-game basis.

Games are not like a spreadsheet or a wordprocessor, they cannot be put out a piece at a time and they have to be written FAST by a group dedicated to just one game.  3D immersive games require a huge pool of expertise in the API of that particular game and so it has to be a full-time job if you are to be effective.  Look at FreeCiv and you will see how a game fares under the current model (I LIKE freeciv - but it has no polish and will never be popular enough to challenge Sid Meier's work).

I don't see the game vendors helping out much because they have nothing to gain.  But the MMORPG world has a lot to gain.  Linux folk are the group best suited to taking an online game and improving the living CRAP out of it.  I have long suspected that those types who are attracted to Linux may be the ones who prefer the virtual worlds of MMORPG.

Perhaps EverQuest could benefit from opensourcing AND providing some monetary incentives to developers of an Everquest version on Linux.  We would still be paying monthly for the service, but breaking no rules of the GPL.  

Has anyone looked into this?

----------

## jtheisen

I'd like to add that in when I tried it, I had to explicitly set IP addresses for ppp by putting the line

```
10.0.2.15:10.64.64.64

```

in the /etc/ppp/peers/slirp file. I took the addresses from the log files where they were claimed to be automatically chosen when the explicit setting was absent. This makes it a mystery to me why I have to specify them, of course, but the connection immediately brakes off after slirps start otherwise. Both peers claim that the other side broke the connection in their logs.

Then,

```
route add -host $TUNNELHOST gw $ENCAPGW 
```

in /sbin/tunnel-up seems redundant to me. $TUNNELHOST will be routed through $ENCAPGW anyway, as that is the default gateway and the new interface won't change that. The remote hosts IP address within the tunnel isn't $TUNNELHOST.

Also worth mentioning are the debug options for slirp

```
-d <some log file>

-dppp

```

in .slirprc or as command line options to slirp. This does't appear to be document properly (how to get a list of all options?). And one can put "debug" into /etc/ppp/peers/slirp in order to make the ppp side log.

Excellent howto, thank you very much! My first try with this was in order to trick a certain internet broadcaster to stream a football game my girlfriend wanted to see from Germany to the UK though it was restricted to German internet addresses. I have a vserver in Germany I can route through, so I used that.

For some reason, it wasn't feasible: it's horribly slow. Where I can download from the ubuntu mirrors with over 400K/s, through the tunnel it's down to 10K/s. It can't be the vserver connection or performance, as I then had the idea to use vlc as a video proxy, which worked nicely.

This leaves the question why the tunnel is so slow in my case. Has anyone got a fast tunnel? Any ideas?

----------

