7

I'm using VirtualBox OSE on Ubuntu 10.04.

I have a Windows 7 guest VM which I use almost exclusively for MS Outlook to access my Exchange mailbox. If I click a URL in Outlook it obviously opens in IE in the guest VM, is there any way to have it perform a redirect of some sort?

If I click a URL inside the VM, I want it to load in my default browser in the Ubuntu host.

  • 1
    No, dont really think so. (Security is one point in using a VM, and this would totally ruin that point I guess if a VM can manipulate the OS this easily. VirtualBox is one hell of a software, but still does at least this much.) – Apache May 12 '10 at 8:11
  • I figured it was a long shot, was hoping someone had a dirty hack to make this work.... guess not. :-) – ThatGraemeGuy May 12 '10 at 8:25
  • I don't agree it would have to be a security hole. I filed a bug to add a URL handler to Guest Additions. If you are trying to host Malware in a VM, then you wouldn't install Guest Additions to begin with (it gives access to video, etc.). – docwhat Jun 6 '11 at 14:36
2

If there was such a way, it would be an enormous security hole.

The most you can do is use the Shared Clipboard: With Guest additions installed, the clipboard of your guest OS can be shared with your host OS.

  • I have been using shared clipboard (when I remember) but it is a little tedious. – ThatGraemeGuy May 12 '10 at 8:35
  • @Graeme Donaldson: I don't believe there's any other way. – harrymc May 12 '10 at 12:24
  • 1
    Sure, the Guest Additions could add a URL handler. The Guest Additions already has out-of-band communication with the VirtualBox and the Host. – docwhat Jun 6 '11 at 14:37
5

Theoretically yes. You could have a stub handler within the guest send a message to a daemon running on the host which actually invokes the proper application. I've never seen such a setup myself though.

  • I'm almost tempted to throw one together in ruby. On Linux I'd use gnome-open and listen only on the virbr0 interface. On windows, I'd probably still use ruby to send the message. – docwhat Jun 6 '11 at 14:43
2

I had the same idea as Ignacio Vazquez-Abrams and I implemented it.


So the first part of this is an HTTP server that listens to requests on the machine where you want to open the browser. On an incoming request it opens (in a browser) the URL given as an argument of a POST request.

Pick one:

You should add this script to startup, it's supposed to run in the background.


The second part is something that invokes the request.

Pick one:

You should designate this script as your default browser. How to do that is... a separate question. You can search for something like "windows set custom executable as default browser".

It can also be used as a command line tool: ./open_url.py 'http://google.com/'


The Python scripts should work on all major systems with any reasonably recent Python version (I suspect 2.6+, 3.1+).

On Windows, if you don't want a Python script to run in a command window, you should change its extension to .pyw. Use Task Manager if you want to stop it (look for pythonw.exe).

VirtualBox network adapter should be set to NAT (default setting). More about the IP address here. The choice of port is arbitrary, feel free to change 1337 to something else everywhere.

The server is secure because it listens only to connections from localhost. VirtualBox makes it work somehow. But if you want this to work remotely, specify the listening IP address as '0.0.0.0' or '' instead of 'localhost'.

  • After all these years, finally someone has done this. Great job, Oleh Prypin. This is working perfectly. It should be upvoted. – shivams May 17 '16 at 11:19
1

If you're using Google Chrome as your browser on both OSs, push browser may help: http://pushbrowserapp.com/

It's basically an extension that lets you send tabs from one device to another, currently supporting Chrome and iOS devices. In your situation, you'd click the link in Outlook, it'd open in Chrome in the VM, you'd click the push browser icon, and the tab would open in Chrome on your ubuntu machine.

0

I'm in the same situation. Here's my better than nothing solution:

I created the script ~/bin/pburl that contains:

#!/bin/bash

set -eu

exec gnome-open $(xclip -out -selection clipboard)

# EOF

What this does is takes any URL you have in your clipboard and opens it as a URL using gnome's default url-handler (Chrome in my case).

My usage is:

  1. In Outlook (on the Guest) I "copy hyperlink".
  2. I click on the desktop or a non-VM window.
  3. I press control-space which launches Synapse and type pburl.

Presto! The URL opens.

It's not as good as just clicking would be, but it does shorten the whole copy-open-browser-paste routine.

0

I don't have 50 points, so I can't comment under Oleh Pyrpin's post.

I have some improvements:

  1. Oleh and I corresponded privately and he provided info on how to setup a systemd user unit. This can be used to run the script at boot within the user session (so it sees the users browser). Instructions are here: [https://gist.github.com/oprypin/0f0c3479ab53e00988b52919e5d7c144][1]

  2. I made some improvements to the Python server code. I am running Host Only Networking in VirtualBox and using iptables to route certin things out of the VM. I found that the server python script would crash if VirtualBox's network wasn't up. My modification checks if the network is ready and if not sleeps for 10 seconds and tries again.

    #!/usr/bin/env python
    # Credit to... Oleh Pyrpin for all of the cool stuff here.
    # See https://superuser.com/questions/140234/is-there-a-way-to-redirect-a-click-on-a-url-in-a-virtualbox-guest-to-open-in-t
    #
    # My improvements:  1. Wait for VirtualBox network to be available 
    #                   2. Check for available port so we can fail gracefully if something (probably another instance of us) is already listening on the port
    # markd89
    
    
    import webbrowser, time, socket, os.path, sys
    
    try:
        from urllib.parse import parse_qs
    except ImportError:
        from urlparse import parse_qs
    
    def application(environ, start_response):
        try:
            if environ['REQUEST_METHOD'] == 'POST':
                try:
                    length = int(environ['CONTENT_LENGTH'])
                except KeyError:
                    length = None
                post = parse_qs(environ['wsgi.input'].read(length).decode('utf-8'))
                [url] = post['url']
                webbrowser.open(url, new=2, autoraise=True)
    
        except Exception as e:
            print(repr(e))
    
        start_response('200 OK', [('Content-Type', 'text/html; charset=utf-8')])
        return []
    
    
    if __name__ == '__main__':
         while True:       #Loop every 10 seconds until we're able to start the Web Server
    
           if os.path.isfile('/sys/class/net/vboxnet1/operstate'):
               print("Debug: Path exists.")
               if 'up' in open('/sys/class/net/vboxnet1/operstate').read():             # Adjust this for the name of your vbox network
                    print("Debug: vboxnet1 is up. Checking if port is available.")
    
                    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    sock.settimeout(2)                                                  #2 Second Timeout
                    result = sock.connect_ex(('192.168.10.1',1337))                   # Adjust this for the server and port you are using.
    
                    if result == 0:
                        print ("Debug: Port already in use. Maybe another instance of this script is running?")
                        sys.exit(1)
    
                    else:
                        print ("Debug: Port available, starting web server.")      
                        from wsgiref.simple_server import make_server
                        httpd = make_server('192.168.10.1', 1337, application)        # This should match the server and port above, doh!
                        httpd.serve_forever()
    
               else: print("Debug: vboxnet1 is not up yet.")
           time.sleep(10)   
    
  3. I implemented the Windows guest side slightly differently. I have a windows port of curl (source unknown, sorry). I figured I would use that rather than install Python on the Windows system. If you don't have curl, you can use the client python script provided in the first link.

I created a batch file url_redirect_client.bat containing:

   @curl --data-urlencode "url=%~1" http://192.168.10.1:1337/
   @exit
  1. I made the above batch file the default Windows web browser and handler of .htm and .html with this registry key:

    Windows Registry Editor Version 5.00
    
    [HKEY_CURRENT_USER\Software\Classes\.CSS]
    @="urlredirectclient"
    
    [HKEY_CURRENT_USER\Software\Classes\.HTM]
    @="urlredirectclient"
    
    [HKEY_CURRENT_USER\Software\Classes\.HTML]
    @="urlredirectclient"
    
    [HKEY_CURRENT_USER\Software\Classes\urlredirectclient\shell\open\command]
    @="c:\\temp\\url_redirect_client.bat \"%1\""
    
    [HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice]
    "Progid"="urlredirectclient"
    
    [HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice]
    "Progid"="urlredirectclient"
    
    [-HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.css]
    
    [-HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.htm]
    
    [-HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.html]
    

I have been running this for a few days and it seems to work well. I ran into one issue with an extremely long url from Amazon, this failed. Possibly, using the original authors client side python script won't have that issue or perhaps it needs someone else to further build on this and improve it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.