streisand vpn

Create Your Own Personal VPN Proxy with Streisand

By now you’ve probably heard a lot about protecting yourself online with a VPN Proxy. You’ve probably even heard the names of some of the top VPN Proxy providers – NordVPN, TorGuard, Tunnel Bear – and my personal favorite Private Internet Access…a service I use daily, and highly recommend (if you’re interested, here’s my PIA affiliate link – much appreciated!).

But, what does a VPN Proxy do exactly? Well – there’s two parts…the VPN, and the Proxy. Essentially, you are creating a secure ‘tunnel’ between you and a random computer server located somewhere around the globe. From there is where you do all of your web surfing, YouTube watching, file downloading, etc. If you’re connecting to a server in Seattle, Washington, you appear to the Internet as some random IP address in Seattle, Washington no matter what your actual location is. That’s the proxy part – you are not surfing the web directly out of the IP address that was given to you by your ISP – you’re someone else, and anonymous. Your ISP can see perhaps how much bandwidth is being transferred from the Internet to your home, but because the tunnel is encrypted with VPN – they can’t tell what you’re downloading, where you’re surfing, or what you’re watching.

I like to imagine a big opaque garden hose stretching across your yard. The ISP can hear that liquid is flowing through the hose, but they don’t know where that liquid is going, or even what kind of liquid it is.

There are a ton of other advantages and benefits to using a VPN Proxy besides the security aspect as well. Bottom line is that using a VPN Proxy is a really great habit to have – your ISP can’t watch you. But then…this brings up a logical next question. Are you just picking a different ‘watcher?’ Who’s to say that your VPN Proxy service isn’t storing all sorts of information about you and then selling it to the highest bidder? Or happily handing over years worth of server logs to everyone who comes knocking with a subpoena?

Most VPN Proxy services have very clear policies about this stuff. In the case of Private Internet Access, they claim to not keep any traffic or access logs, and even have a Transparency Report that shows how many warrants and subpoenas they have received and complied to. But of course, the Internet being the skeptical den of villainy that it is, a lot of people are still not convinced that any 3rd party VPN Proxy service is trustworthy.

Well – good news! You can build your own. There’s a fantastic project on Github called Streisand – as in the Streisand Effect, or the phenomenon by which an attempt to hide, remove, or censor a piece of information has the unintended consequence of publicizing the information more widely. Back in 2003, Barbara Streisand made a big stink about trying to suppress photos of her Malibu, California home. It became such a big story that it actually drew a lot more attention to the home than it would have if she had just stayed out of it.

So – let’s set up our own personal Streisand VPN server. This project is great for learning how to work with a cloud server provider such as Digital Ocean, and it has a decent amount of Linux and networking as well. I would rate this an intermediate skill level project – but really satisfying once it’s up and running and protecting you from your big bad ISP.

This project tries to automate the server setup as much as possible – they’ve really done all of the heavy lifting for you. But, these instructions will walk you through the setup start to finish – if you follow these steps exactly, you will have a working Streisand server at the end. And – like all of my projects, I will do my best to keep this documentation up to date as things change.

With that being said – this project is intermediate level – this blog post and accompanying YouTube video will get you all the way up and running from zero to having a fully functional VPN Proxy server. However – and this is COMPLETELY OPTIONAL – if you are interested in supporting Crosstalk’s efforts in documenting this process, we are offering for purchase a downloadable PDF version of these instructions which additionally includes 12 extra pages of information on connecting client devices (Windows 10, iOS, and Android) to the VPN Proxy. Again – you don’t need the PDF, but if you want it, it goes further than these instructions. Beyond the server setup and into the client setup as well.

UPDATE: 1/28/2021 – the Streisand documentation is getting a bit stale, so I have removed the PDF from the store. It is no longer available to buy or download.

To set up Streisand, we’re going to need two separate DigitalOcean servers – the first server will be our Builder, and the 2nd server will be our VPN Proxy. The Builder server is just that – we’re creating a freshly installed Ubuntu Linux server that will be in turn used to automatically build our VPN Proxy server through a series of scripts and automated steps.

You can use an existing server as your Builder – but if you stray from these instructions at all, you had best have a really decent knowledge of what you’re doing. If you’re still learning, just stick with these steps and you’ll be good – the Builder server on DigitalOcean costs $5.00/month, and you only really need it up and running for a few hours to get this done…it’s worth a few pennies to start with a clean foundation.

Step 1 – Log into DigitalOcean

If you do not yet have a DigitalOcean account, please consider using my DigitalOcean affiliate link to sign up – it’ll get you $100.00 worth of DigitalOcean credit (over 60 days) – way more than you would ever need for this project.

Step 2 – Create your Streisand Builder server

Once logged into your DigitalOcean account, click Create –> Droplets. Choose an Ubuntu 16.04 x64 droplet – Standard Plan, $5.00/month tier.

Ubuntu 16.04 x64, Standard, $5.00/month tier

Scroll down further until you get to ‘Choose a datacenter region.’ Here you can select any region you like – since this is for the builder, I’m just going to select a region that is geographically close to me.

Next give your Builder a hostname – doesn’t have to be an actual FQDN – this is just a name for our Builder. I’m going to call mine ‘streisandbuilder’ and then click ‘Create.’ DigitalOcean will take about 30-60 seconds to spin up your new server. In the meantime, you will receive an email with the root user password and the IP address you want to connect to with your SSH terminal emulator (I use PuTTY).

Pick your data center, name your Builder droplet

Step 3 – Log into your Streisand Builder server and prep it for action

Once your Streisand Builder droplet server has been created, you can log into it via SSH with the root password you received in email.

Email from DigitalOcean

Upon your first login, you’ll be asked to change your root password. Make this something strong, and don’t lose this password – you’ll need it as long as you want to connect to your Builder server.

The first thing we’re going to do is create a SSH keypair:


Just hit ‘ENTER’ 3 times to take all of the defaults. You now have a public/private keypair and you can see it by typing:

ls -la .ssh

You will see the private (id_rsa) and public ( keys in this folder. It would be wise at this point to take a backup of both of these files – not because we’re going to use them with THIS server (we’ll be destroying this server after we’re done), but these are the keys that we’re going to use to connect to our actual VPN Proxy server.

Next, we’re going to install our bootstrap packages – or in other words, we’re downloading all of the programs necessary to run the scripts that will create our VPN Proxy server.

sudo apt update && sudo apt install git python-pip -y

This should take about 1 minute to complete.

Step 4 – Download and execute scripts for Streisand VPN Proxy server creation

Next, we’re going to ‘clone’ the Streisand software from Github. This basically just means we’re grabbing a copy of the software.

git clone && cd streisand

We should now have the software and we have changed directory into the Streisand directory. Next we’re going to run the installer for Ansible and its dependencies. Ansible is an IT automation engine for running scripts and executing programs. This program that we’re about to run will check for any missing software that we’re going to need (dependencies). It will then display an additional command that we can run to install those dependencies. THIS IS VERY IMPORTANT! The first time I went through this process, I didn’t realize that THIS command generates another command that we are going to want to run.

./util/ ./venv

The output of that command will show you a new command that you will want to run:

The FIRST time you run this command, it shows you what needs to be installed so that it can be successfully run a SECOND time.

In my case, the command that it wants me to run is:

apt-get install python-cffi libffi-dev libssl-dev libcurl4-openssl-dev

The command that is displayed to you MAY BE DIFFERENT – so pay very close attention here. After you run the command you can answer ‘Y’ when prompted. When that command has completed, we have now installed everything needed to install Ansible and all of its dependencies – run that same previous command again:

./util/ ./venv

Now we’re cooking with gas! This script takes a minute or two, and you can ignore any Python 2.7 warnings or errors (may show up as red text).

Step 5 – Create the VPN Proxy Server

Now comes the fun part – we’re all ready to create our VPN Proxy Server. First, activate the Ansible packages that we installed:

source ./venv/bin/activate

You should notice that the command prompt changes – it should now have a (venv) in front of it. Finally, let’s execute the Streisand script:


The first question we’re asked is which Cloud Server provider we’re using. In our case, it’s DigitalOcean. If you are using any other provider such as AWS, Linode, or Rackspace, this entire process is very similar, but you’ll have to adapt these instructions to the nuances of those platforms.

Choose the option for DigitalOcean – in our example, it’s Option 3.

Press 3 ‘ENTER’ to move to the next step

Next, we’re asked if we want to customize our installation – type ‘no’ and press ENTER.

‘no’ we don’t want to customize ‘ENTER’

Next, we are asked for our DigitalOcean region. This is basically asking us which DigitalOcean data center do we want to use for hosting our VPN Proxy server. This DOES NOT have to be in the same data center as the Streisand Builder server – but in my case, I’m going to select the option for the same data center (San Francisco Datacenter 2) and press ‘ENTER.’

Pick a data center for your VPN Proxy Server.

What should the server be named? This is NOT the fully qualified domain name for the server (though it can be the same) – this is the name of the DigitalOcean droplet server as it will appear in the DigitalOcean interface. For mine, I’m going to call it StreisandVPNServer. You can also optionally just press ‘ENTER’ to take the default name (streisand).

Pick the name of your DigitalOcean droplet and press ‘ENTER’

Once we have selected our DigitalOcean droplet name, we are now asked to enter in our DigitalOcean Personal Access Token – we don’t have that yet, so let’s go back to DigitalOcean to create it.

Part 6 – Create a DigitalOcean Personal Access Token

From the DigitalOcean dashboard, click on API and then click on ‘Generate New Token.’

Call the token whatever you want – I’m calling mine StreisandVPN – and then click ‘Generate Token.’

Now we have our token – click the ‘copy’ link that pops up when you hover your mouse at the end of the token string, and that token is now on your clipboard. Let’s get back to our Streisand Builder server SSH window.

Part 7 – Complete Streisand VPN Proxy installation

Paste the DigitalOcean Persnal Access Token into the SSH screen and press ‘ENTER.’

Next, we’re asked for the name of the DigitalOcean SSH key that we’d like to use. This is helpful if you are already very well versed in DigitalOcean, and you have a pre-configured set of SSH keys already created. For our purposes however, we just created our keys back in Step 3, so we can just press ‘ENTER’ take the default name of streisand. This will create a new keypair for use with DigitalOcean droplets called streisand, and it will be visible in your DigitalOcean dashboard when you click on Security.

Just press ‘ENTER’

Finally, we’re told that Streisand will now set up our server. Press ‘ENTER’ once again and the process kicks off. You will see a whole list of steps and tasks flying past the screen – this is the Ansible script in action. Don’t worry if it seems to stall or pause for long periods – this is normal.

After about 1 minute, you are prompted for your Fully Qualified Domain Name (FQDN). At this point we need to pause to create a DNS A-record that we can use to connect to our VPN Proxy Server. You DO NOT want to skip creating this DNS A-record…our server is going to be protected with Let’s Encrypt, and Let’s Encrypt won’t work without a valid FQDN.

Go back to your DigitalOcean dashboard and click on Droplets. At this point, you should see that a brand new droplet server has been created. Write down/note/copy the new VPN Proxy Server droplet’s IP address.

Go back to DigitalOcean and get the IP address of your new VPN Proxy Server

Step 8 – Create DNS A-record

Pick your DNS name – it can be whatever you want. I’m going to pick

Now that I have my FQDN picked, I need to create an A-record in DNS so that anyone who looks up my FQDN will resolve to my DigitalOcean VPN Proxy Server IP address.

I use SiteGround as my hosting provider (they are excellent) – and SiteGround uses cPanel for setting up DNS records – your domain name hosting and DNS settings are probably going to be different than mine – so I can’t specifically document this part of the process.

However, if you have created the A-record successfully, you should be able to ‘ping’ your FQDN and receive a response – the response will be the IP address of your DigitalOcean VPN Proxy Server.

PING your FQDN – the reply should come from your DigitalOcean VPN Proxy server droplet

Once your DNS A-record is working properly, you can go back to the Streisand Builder Ansible script, enter in the FQDN and press ‘ENTER.’ to continue the script. DOUBLE-CHECK that you typed the FQDN correctly first!!

Double-check that you are entering the FQDN correctly!

Step 9 – Finalizing the VPN Proxy Server script

Finally, the script asks us for an email address – this is OPTIONAL. If you do enter in an email, Let’s Encrypt will use it to send notifications about the SSL certificate that is created on the server (for instance if there’s a problem renewing).

Enter in an email for Let’s Encrypt notifications (optional)

Now the script will finish up all of its tasks and kick you back out to the command prompt. This takes a while, so be patient! For me, it was about 14 minutes. If, during the installation, you received any errors, don’t panic – in my case, I received 2 verification errors that looked like this:

Scary error huh?

This doesn’t seem to affect the server at all, so these errors can be safely ignored – BUT – 2 errors is what I received in total…if you have WAY more than that, you probably did something wrong. If you proceed onto the next steps and you’re having trouble connecting devices to the Streisand VPN Proxy server, you may have to restart this process from scratch – chalk it up to a good learning experience!

My final summary report – 2 failures – but not a big deal.

All done! Your Streisand VPN Proxy has now been created – but…how do you access it?

Step 10 – Connecting to your Streisand VPN Proxy server

Once your server has finished building, you should still be sitting at the Builder server prompt, and the script that we ran over the last few steps has created a personalized HTML file for us to take a look at. Change directory to the following:

cd ~/streisand/generated-docs

In this folder, you should see a couple of generated docs (and their French language duplicates). StreisandVPNServer.html contains your Streisand VPN Server GUI username and password. StreisandVPNServer-firewall-information.html is a summary of all the ports that are open on your new VPN Proxy. Note that the ‘StreisandVPNServer’ portion of the filename is whatever you called your Digital Ocean droplet in Part 6 of this guide.

If you would like to connect in and download a copy of these documents (highly recommended), you can use a program called WinSCP. Use WinSCP to connect to your Builder server and navigate to /root/streisand/generated-docs/. As indicated below, click ‘New Site’ and then select ‘SCP’ as the File protocol. Enter in your Builder server IP, username (root) and password and then click ‘Login.’

How to connect to your Builder server with WinSCP

Once connected, navigate to /root/streisand/generated-docs and you’ll see the files needed to connect to your Streisand VPN Proxy server. Download a copy of these files and keep them in a safe place. You can also right-click on the StreisandVPNServer.html file and select ‘Open’ to immediately open that file in a browser and view your Streisand VPN Server login information which includes the username ‘streisand’ and a randomly generated passphrase. Click your Streisand VPN Proxy server’s FQDN and then log in with the given username and passphrase.

Your VPN Proxy server connection info – click your FQDN to log into your Streisand server.
Enter your login information into the Streisand VPN Proxy server.

Once logged in, you will see Connection Instructions for a wide variety of VPN clients as well as instructions on creating an SSH proxy which allows you to create an SSH connection to the server that allows you to browse through FireFox as a SOCKS proxy.

Each one of these options gives you full instructions for how to connect using the selected method. I personally recommend using either OpenVPN (direct) or SSH to connect to the Streisand VPN Proxy server.

You now have all of the tools you need to connect to your Streisand VPN Proxy server.

Step 11 – Connect to your VPN Proxy using SSH

Connecting to your Streisand VPN Proxy server via SSH gives you two advantages – first, you can actually SSH into the server itself in order to update software and make configuration changes.  Second, once connected, our setup will allow you to configure FireFox as to use the VPN server as a SOCKS proxy meaning that any surfing you do with FireFox will be travelling through your Streisand VPN Proxy server.

We’re going to be deviating from the instructions in the Streisand VPN Proxy server GUI (the ones under ‘SSH’ – those instructions work perfectly – and I encourage you to try them), however they don’t allow for root access to the VPN Proxy server.  To do that, we first need to convert the private key that we downloaded in Step 3. To do this, we’ll use another free program from the creators of PuTTY called PuTTYgen (you can download it from the same link as PuTTY above).

First, run PuTTYgen and click the ‘Load’ button.  Browse to the private key file that you saved in Step 3.  When browsing for your private key, change the file type you are searching for from ‘PuTTY Private Key Files (*.ppk)’ to ‘All Files (*.*).’

Open your private key file, and you should receive a notice that the private key was successfully imported.  Click OK to get off of this notification.

Now, click the ‘Save private key’ button and save your private key as a .ppk file (I usually just use the same directory that I used to save the original private key).  You can now close PuTTYgen.

Use PuTTYGen to convert your private key to a .PPK file

Now, we’re going to open PuTTY to connect via SSH. Create a new PuTTY session and enter the following information in the Session category:

Host Name: (your own FQDN or IP address)

PuTTY Session settings

Next, click on Connection → SSH → Auth and click ‘Browse.’  You’ll want to browse to the .PPK file you just created with PuTTYGen.  

PuTTY Connection –> SSH –> Auth settings – browse for your .PPK file

The next step is to click on Connection → SSH → Tunnels.  Enter 8080 into the ‘Source Port’ field, and select the ‘Dynamic’ option down towards the bottom of the window.  Click on ‘Add’ and then you should have a ‘D8080’ appear in the ‘Forwarded ports’ list.

PuTTY Connection –> SSH –> Tunnels settings – create a tunnel through to your VPN Proxy Server

Here is what it looks like after you click ‘Add.’

Correct tunnel settings

Finally, we can click back to ‘Session.’  We’re going to save this session so that you don’t have to enter in all of that information again – give it a name in the ‘Saved Sessions’ box and then click ‘Save.’

Save your PuTTY session so that you don’t have to repeat all of that work!

The next time you want to open this same session, just click on your saved session name (in my case, it’s called StreisandVPNProxy) and then click ‘Load’ followed by ‘Open’ to connect.

When the session opens, use username ‘root’ and you should authenticate with your private key file (no password needed).

Now that’s part 1 – connecting to SSH.  But remember that we also added a source port of 8080 when setting up our PuTTY session.  This means that with this connection established, if we use FireFix to route our browser traffic out through our local computer ( on port 8080, we should be browsing securely through our Streisand VPN Proxy server.

Open FireFox and click on the Open menu followed by Options.

FireFox Options

When you have the Options open, scroll all the way down to the bottom of the options page and click on ‘Settings’ in the Network Settings section.

Network settings

Select ‘Manual proxy configuration’ and then enter in SOCKS Host and Port 8080.  Click ‘OK’ to save this setting.

Manual proxy configuration settings

Now, let’s test it out.  If you open up a new FireFox tab and browse to (or you should see your WAN IP address, and it should be the same IP address as your Streisand VPN Proxy server.  This means that you are now hidden – you’re not appearing to the Internet as your ISP’s given IP address – you are now obscuring your activity with the VPN proxy server.

Check your WAN IP address – it should be showing the IP address of your VPN Proxy server

Step 12 – Fix OpenVPN configuration settings

When you first set up your Streisand VPN Proxy server, the OpenVPN settings are not correct. Log into your VPN Proxy server with SSH and edit the following file:

sudo nano -w /lib/systemd/system/openvpn@.service

Inside that file, you’ll want to find a line that shows LimitNPROC=10. Change it to:


Once you’ve made that change, hit CTRL+X followed by Y and ENTER to save and exit.

We’re not done yet though – you’ll need to make that same exact change in two more files:

sudo nano -w /etc/systemd/system/openvpn@server.service
sudo nano -w /etc/systemd/system/openvpn@server-udp.service

Once you have made all of those changes, run:

systemctl daemon-reload && reboot

(The Daemon reload may be redundant, but it doesn’t harm anything to run it anyway). Once the server has rebooted, reconnect, and now you should be able to connect your PC/Mac/iPhone/Android clients.

Step 12 – Connect your Clients!

For your convenience, I have also created a PDF version of this documentation. This PDF document includes everything up to this point, and additionally includes detailed instructions for connecting to your VPN clients (iPhone, PC, via SSH, etc.) – yes you can absolutely use the Connection Instructions in the generated docs, but if you would like to support Crosstalk Solutions and our efforts to document this process, please head over to our store to purchase a PDF copy of this documentation – PLUS all of the extra documentation. Much appreciated!

UPDATE: 1/28/2021 – the PDF version of this documentation is no longer available for purchase or download. It was getting a bit stale.

Comments 15

  1. I followed your instructions, and my clients can connect to the VPN server just fine, but I cannot access anything on the internet. Do you know of any step I might need to do to get that to work? Thanks.

    1. Post

      Keep trying – you’ll get it. There are a TON of different ways to connect clients – did you try all of them with the same result? If that’s the case, then you probably missed a step somewhere. It’s a good learning experience.

  2. I get the following error with Digital Ocean:
    TASK [Wait for cloud-init to complete] *****************************************
    fatal: []: UNREACHABLE! => {“changed”: false, “msg”: “Failed to connect to the host via ssh: Warning: Permanently added ‘’ (ECDSA) to the list of known hosts.\r\nPermission denied (publickey).\r\n”, “unreachable”: true}
    to retry, use: –limit @/root/.ssh/streisand/playbooks/digitalocean.retry

    PLAY RECAP ********************************************************************* : ok=1 changed=0 unreachable=1 failed=0
    localhost : ok=10 changed=2 unreachable=0 failed=0

  3. I followed your perfect instructions. Thank you. I am using my Streisand from China.

    I am not sure your DigitalOcean affiliate link is working. I don’t see that I got any credit which means that you may not be getting credit. Is there any way to find out?

  4. Chris, your vid and tutorial are superb! Thanks for sharing.

    I hope you see this post before I take the plunge… Your response could save me many hours of work 😉

    I had a working, custom install of Shadowsocks with Cloak on a generic server. The last Cloak update broke my setup. I’m not having any luck getting help from the devs so I’m leaning towards starting over, dumping Cloak and going with Streisand.

    The Cloak plug-in made all traffic look like simple HTTPS traffic. If someone connected to my server without a Shadowsocks client, the server would serve my website so it appears to be nothing more than a regular webserver. Does Streisand do the same thing? If so, can the web page(s) served by Streisand be edited?

    Do you know if PHP and MySQL can be installed/used on the Streisand server so the server can serve a dual purpose?

    I see Streisand auto updates. Will any customization to the server be lost when it updates?

    I hope you can take the time to answer theses questions. I would hate to wipe my server, install Streisand only to find that it cannot meet my requirements.



  5. Fantastic tutorial!
    Just curious, when we set up the Proxy server in Firefox to go to, what is the significance of that? It definitely works, but I’d like to know why it works that way.
    Thanks for all you do!

  6. After following all steps up to and including ./streisand (and then selecting appropriate options), the streisand script fails with the following error (below).

    Prior to this, the script was running longer but when completed there were no html document files (so I decided to start over and now I’m getting this issue).

    I have tried both ensuring there are no SSH keys in my DO settings to adding the pub ssh key generated and using that name when prompted in the streisand script. Have also tried deleting and re-adding API PATs. Not sure what is going on.

    TASK [genesis-digitalocean : Add the SSH key to DigitalOcean if it doesn’t already exist] *************************
    fatal: [localhost]: FAILED! => {“changed”: false, “module_stderr”: “/root/streisand/venv/lib/python3.5/site-packages/OpenSSL/ CryptographyDeprecationWarning: Python 3.5 support will be dropped in the next release ofcryptography. Please upgrade your Python.\n from cryptography import x509\nTraceback (most recent call last):\n File \”\”, line 114, in \n File \”\”, line 106, in _ansiballz_main\n File \”\”, line 49, in invoke_module\n File \”/usr/lib/python3.5/\”, line 234, in load_module\n return load_source(name, filename, file)\n File \”/usr/lib/python3.5/\”, line 170, in load_source\n module = _exec(spec, sys.modules[name])\n File \”\”, line 626, in _exec\n File \”\”, line 665, in exec_module\n File \”\”, line 222, in _call_with_frames_removed\n File \”/tmp/ansible_digital_ocean_sshkey_payload_5umuq8gr/\”, line 265, in \n File \”/tmp/ansible_digital_ocean_sshkey_payload_5umuq8gr/\”, line 261, in main\n File \”/tmp/ansible_digital_ocean_sshkey_payload_5umuq8gr/\”, line 170, in core\n File \”/tmp/ansible_digital_ocean_sshkey_payload_5umuq8gr/\”, line 107, in json\n File \”/usr/lib/python3.5/json/\”, line 312, in loads\n s.__class__.__name__))\nTypeError: the JSON object must be str, not ‘bytes’\n”, “module_stdout”: “”, “msg”: “MODULE FAILURE\nSee stdout/stderr for the exact error”, “rc”: 1}

    TASK [genesis-digitalocean : fail] ********************************************************************************
    fatal: [localhost]: FAILED! => {“changed”: false, “msg”: “* The API Access Token might be incorrect or missing the Write Scope. OR * The SSH key may already exist in the DigitalOcean Control Panel under a different name.”}

    PLAY RECAP ********************************************************************************************************
    localhost : ok=4 changed=0 unreachable=0 failed=1 skipped=0 rescued=1 ignored=0

Leave a Reply

Your email address will not be published. Required fields are marked *