Tag Archives: Linux

OpenVPN could connect but did not ping internal network

I’m setting up my internal infrastructure to use OpenVPN since I want to be able to do a lot of monitoring on the Notiffi system I’m working on and I didn’t want to use an SSH tunnel and I definitely did not want to be sending instrumentation data across the Internet without protection.  So I decided to use OpenVPN.

But I had a problem.  I was able to connect relatively easily but I could not ping the machines.  Routing seemed to be working properly

1
2
ip -s route get 192.168.1.1
192.168.1.1 via 192.168.1.5 dev tun0 src 192.168.1.6

and tcpdump was showing traffic over the main eth.

1
2
3
4
tcpdump -nnel -i eth0 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
16:26:18.860693 90:6e:bb:82:ec:38 > 00:18:4d:7b:a8:1f, ethertype IPv4 (0x0800), length 95: 69.164.199.69.43655 > 192.168.15.2.1194: UDP, length 53

But pings were not working.  Tried to figure this out for hours, but I just couldn’t find the solution.  Then as I was checking the errors logs (after reducing the log level to 1) and I saw this

1
Oct 18 16:14:58 localhost openvpn[29751]: 69.164.199.69:43648 WARNING: 'comp-lzo' is present in remote config but missing in local config, remote='comp-lzo'

That was on the server.  I checked the logs on the client and I saw

1
Oct 18 16:19:58 li114-69 openvpn[32078]: Bad LZO decompression header byte: 42

And it got me wondering if there was just a communication problem due to one side expecting compression and the other side not.  In other words, that it wasn’t negotiated.  I made the configuration change on BOTH ides this time, tried the ping again and it worked.

1
2
3
ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=63 time=0.208 ms

Nice.

Debug Tunneling

Debugging is one of the things that every single PHP developer in the world needs to know how to do.  Unless you are simply learning the language, learning how to debug will save you countless hours and save you loads of money in anti-anxiety medications.  var_dump() or print_r() is not debugging. At least, it's not debugging in a way that is very useful, or safe. 

There are two primary debuggers in the PHP world.  XDebug and the Zend Debugger.  I am not an expert in XDebug (though I really need to learn it better) so I will leave those discussions to someone else. 

Debugging on a local workstation is really quite simple.  I use the Zend Debugger Toolbar in my browser when I'm not debugging a Unit Test (how I usually test functional components, as opposed to visual components).  The reason I do this is because it's much easier to debug a certain context, such as a logged in admin user, than using the internal browser in Eclipse.  The toolbar is installed when you install Zend Studio or you can download it seperately and install it in Firefox manually.

The debugger toolbar

This works very easily when you are working in an environment with very few restrictions, such as a debug environment.  However, say you run into a problem in your testing or staging environments?  (I could also add your production environment, but you should actually never have the debugger installed on a production environment for security reasons.)  The way the debugger works is that Zend Studio opens up a port on the local machine so that when a debug session is kicked off, the debugger in PHP will open up a TCP connection back to Zend Studio and start the debug session.  The problem is that testing and staging environments often have outbound port restrictions, for good reason.  But that makes debugging an issue in one of those environments a little tricky.

The solution is the debug tunnel.  What Zend Studio does is instead of waiting passively on the local machine for a connection to come in, it will open up an HTTP connection to the remote server.  Then when a debug session occurs the debugger extension will communicate over a local port, which then forwards the debug information back to Zend Studio over HTTP.  The data is the same, it's just being tunneled over HTTP.  Because there is no outbound connection initiated and because the communication is occuring over port 80, if you can connect to the web server you can debug on it.  It should, however, be noted, that tunneling does not work on Windows systems.  I don't know the exact reason, but I would venture to say that it is due to PHP on Windows running as a FastCGI instance.  This would likely conflict with the long running request required to facilitate a debug tunnel.

The way this is done is by Zend Studio making a connection to a debug file.  That file is usually called dummy.php and contains the following code.

@ini_set('zend_monitor.enable', 0);
if(@function_exists('output_cache_disable')) {
        @output_cache_disable();
}
if(isset($_GET['debugger_connect']) && $_GET['debugger_connect'] == 1) {
        if(function_exists('debugger_connect'))  {
                debugger_connect();
                exit();
        } else {
                echo "No connector is installed.";
        }
}
?>

This code turns off all of the timers in monitoring, disables the cache and then checks to see if a debug tunnel is being requested.  If so, it basically sites on the debugger_connect() function.  This function will open up a port on the local interface and wait for connections to come in.  This file does not need to be on the domain name of the web site you are trying to debug.  In fact, just so you are sure that you don't accidentally deploy the dummy.php file it would be a good idea to have a seperate virtual host on the Apache server where it would reside.

On the Zend Studio side what you now need to do is set up the tunneling.  That is done by clicking on the arrow next to the tunneling button and clicking on "Servers".

Step 1

Clicking the Server button

Step 2

Selecting the server

Step 3

Enabling the tunnel

Step 4

Enabling the tunnel.

Step 5.

All done

With that, you should be golden.  Or in this case, green.

If you are using the Zend Studio toolbar you can test to actually see this working.  Simply go to Extra Stuff -> Settings and click on "Test".  You should see something similar to this.

Testing the connection

Go to your Linux server and then type in "lsof -i | grep |PORT|" replacing |PORT| with the port in the window.  In my case, 57192.

httpd     3016     apache    8u  IPv4 4100270       TCP *:57192 (LISTEN)

As you can see we have a connection setting there.  If we now do the same thing, but grep for the PID (3016) you can see our connection via our tunnel.

httpd     3016     apache    7u  IPv6 4100269       TCP li114-69.members.linode.com:http->xxxxxxxxxx:news (ESTABLISHED)
httpd     3016     apache    8u  IPv4 4100270       TCP *:57192 (LISTEN)

All done.