Monthly Archives: January 2017

Node NodeJS with Lamp on Apache Bitnami Stack

I wanted to test some of the new Facebook Messenger bots and since “The Facebook” requests your services to have https, I wanted to leverage my existing domain that already has ssl setup.  Unfortunately when you pick a Lightsail instance, it’s Node.JS or LAMP.  Since I already had a LAMP instance, my goal was just to have Node running on top.

I was a little hesitant because I didn’t want to have Node conflict with Apache and take down my existing site.  What I learned is that NodeJS (or Node which are the same thing) won’t conflict as you can run your service on another port.  However, there is some setup that you need to take care of.  If you are nervous about messing up an existing instance, just spin up a new light sail instance which is similar to your existing and play around with the package installs on that one.

Install NodeJs

Assuming you already have a Lightsail Bitnami LAMP instance (or similar), you need to install two things:  NodeJS and NPM.  Basically NodeJS is the engine that will run your code and NPM is a package manager.  I was confused on how to get Node and NodeJS both installed not realizing they are the same thing.  The commands to do it are:


sudo apt-get install nodejs
sudo ln -s /usr/bin/nodejs /usr/sbin/node

The 2nd line is to create an alias so that node and nodejs do the same thing

Then install the packages that support the nodejs code


sudo apt-get install npm
npm install

Make sure you run the second line otherwise you downloaded all the packages, but didn’t actually install.

Test you have it working by typing `nodejs –v` and it should tell you the version you have running.

Do a hello world type test now and save these two lines in a script called helloWorld.js


var sys = require("sys");
sys.puts("Hello World");

Now type nodejs helloWorld.js and it should simply say Hello World

Apache Configuration

Next you need to modify your Apache configuration so it knows to pass requests for Node.  For this, you need to know what port your application will run on.  For my setup, I used port 8080.

Open up your /home/bitnami/stack/apache2/conf/bitnami/bitnami.conf file and add these lines to the section of your config that is for port 443


SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
ProxyRequests Off
ProxyPreserveHost On

<Location /webhook >
   ProxyPass http://localhost:8080/webhook Keepalive=On
   ProxyPassReverse http://localhost:8080/webhook
</Location>

The key is the Location section above.  This tells apache that for any request that starts with /webhook to pass the request to what you had configured as the url.

Restart Apache for these settings to be applied.  When it restarts, if you did something wrong, it will show you the error.

To be honest, I’m not sure if all those SSLProxy* config settings are necessary, but that’s how it is working in my environment.

Testing Running  A Server

You should have to make one more Lightsail config, but lets setup a test server to start.

Copy and pasta this into a new file and save it as server.js


var sys = require("sys"),
my_http = require("http");
my_http.createServer(function(request,response){
sys.puts("I got kicked");
response.writeHeader(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}).listen(8080);
sys.puts("Server Running on 8080");

Now start it by running nodejs server.js and it should say “Server Running on 8080”

From another terminal session, on the same server, telnet localhost 8080 and it should connect.  Now try doing it from somewhere externally by typing in the URL of your server and what you configured in the apache config.  For instance, https://www.yourdomain.com/webhook   Remember to use https and not to include the port number as that’s already setup in the config.  If that does not work, then you need to open up port 8080,  Go to your LIghtsail instance, click on Manage, Open a CUSTOM port 8080 and save.  Try it again and it should work.  Another way you can test, which will not be be https is to use http://www.yourdomain.com:8080/webhook  They should do the same thing, except not be encrypted.

Run Node as a Service

Once you ctrl-c out of your terminal session, your NodeJS service will stop.  To keep it running in the background install forever.


sudo npm install -g forever

To start it as a service, simply use this command:


forever -o output.log -e error.log start app.js

This will start the service in the background but also put the output into the log files so you can monitor the interactions. To see if it’s running, just run forever list

Facebook Configuration

The entire point of me doing this was to actually test a Facebook Messenger Bot.  I downloaded the sample code from https://github.com/fbsamples/messenger-platform-samples I had a few issues in getting it to work so here are some hints:

Obviously, update the app.js file to reflect the port you are running the service on.  Search for port 5000 which is what the sample code uses and replace it with port 8080.

Your page access token will sometimes change.  If you are getting this error message Failed calling Send API 400 undefined { message: ‘(#100) No matching user found’, then copy and paste it again in your config/default.json file

Your appSecret is from your developer page, click on the app you setup to test and click “Reveal App Secret”.

If Facebook is kicking back errors from your webhook, you can tail your access and error logs to see what they are sending.  You should see a request like this which you can use to manually debug: /webhook?hub.mode=subscribe&hub.challenge=123343443243243&hub.verify_token=your_test_token_that_you_created

My application would error on start due strict mode.  I had to comment out the line (still need to figure out why).

Also, if your proxy is still not working, try adding this line:  app.enable(‘trust proxy’);

Lastly you can start the code by typing npm start in the directory where app.js is located or do nodejs app.js  I initially didn’t understand the “npm start” command until I realized it simply starts whatever it find in current path.

Hopefully that helps.  Another great tutorial similar to the Facebook one can be found here:  https://github.com/jw84/messenger-bot-tutorial

OpenVPN setup on DD-WRT Router with Mac and iOS 10

Apple removed support for pptp as part of the iOS 10 release.  Apparently pptp is susceptible to man in the middle attacks so I guess that’s a good thing.  The bad thing is that OpenVPN is really really difficult to setup.  You’re going to know some basic things about networking to set it up and be prepared for a lot of frustration.  Here are the important parts to my setup

  • DD-WRT router running build 20180 setup for internal network of 192.168.0.*
  • Using Mac options (not windows)
  • Connect via iPhone (same setup for iPad, have not tested via Mac yet though)

Generate Keys

Similar to how you setup SSL certs for a web server (if you ever have done that), you’re going to have to setup keys for the server (your dd-wrt router) and your client (your iPhone, for instance).   The best guide I found do this is this post from sparklabs.  It will guide you to download EasyRSA and to generate your server and client keys.  Be sure to save them in different directories so you don’t get confused which is which.  Also ensure to rename your dh.pem file to dh2048.pem as it states in the instructions.  For the client .opvn configuration, I renamed mine to match my key name: client1.opvn

Server (DD-WRT configuration)

This was a huge problem for me and nothing seemed to work right.  I’m running build 20180 which seems to be buggy so I had to do a few things manually.  For my setup, my local network is 192.168.0.*  Notice the that the third octet is “0”.  Some folks have .1 or whatever.  That’s what you’ll need to change for how you have your local network setup.

When you setup your OpenVPN you need to pick your VPN subnet.  I picked 192.168.66.*  It doesn’t matter, I just used .66 which was in another tutorial.  This means that any OpenVPN client that connects will be assigned an IP address in that range.  So here we go:

  1. Login to your router.  Hopefully you do this all the time otherwise maybe this is not for you 🙂
  2. Go to Services, VPN, enable OpenVPN Server.  Use these options:

OpenVPN Server: Enable (duh!)

Start Type: WAN Up.  (System option did not work for me and I saw some folks say WAN Up doesn’t work.  It works for me though)

Config via: Config File

CA Cert, Public Server Cert, Private Server Key, DH PEM:  These are the four SERVER certs you created in the previous step.  You need to copy and paste the block of text that ALSO includes —BEGIN CERT… until —END CERT.  Don’t leave those out (they are not comments)

Some tips:

server.crt has a bunch of other stuff in it.  Only copy the cert stuff (again, including the —- lines)

ca.cert = CA Cert (config section in DD-WRT)

dh2048.pem = DH PEM config section

server.crt = Public Server Cert config section

server.key = Private Server Key config section

Ok, now here is the big one.  Add this to the Additional Config section:


dh /tmp/openvpn/dh2048.pem  #you might have dh.pem here and need to fix
ca /tmp/openvpn/ca.crt
cert /tmp/openvpn/cert.pem
key /tmp/openvpn/key.pem
keepalive 10 120
verb 9
mute 3
log-append /var/log/openvpn  #this is where you can view errors/status
writepid /var/run/openvpnd.pid
management 127.0.0.1 5002
management-log-cache 50
mtu-disc yes
topology subnet
client-config-dir /tmp/openvpn/ccd
script-security 2
port 1194
proto udp
auth sha1
comp-lzo yes
tls-server
ifconfig-pool-persist /tmp/openvpn/ip-pool 86400
client-to-client
fast-io
tun-mtu 1500
server 192.168.66.0 255.255.255.0
route add 192.168.66.0 mask 255.255.255.0 gw 192.168.0.1
push "route 192.168.0.0 255.255.255.0"
dev tun

Notice at the end I have some routes setup.  These are very important because they help bridge your internal network with the VPN.  Again, my internal network that connects all my computers at home is 192.168.0.*  The VPN will be 192.168.66.*

Once you have that click Save and then Apply settings.

Then in DD-WRT Admin GUI go to Status, OpenVPN and see if it’s running.  If you don’t see a lot of information, it failed to start.  Here is how you troubleshoot that.

Use Terminal to telnet to your dd-wrt router while on your local LAN.  e.g. telnet 192.168.0.1  When it asks you for your username/password, do not type “admin” as the username.  Use “root”.  Then use the same password you use to login via the web gui.  I didn’t know that you had to use root instead of admin and that screwed me up for a little bit.

Ok, now you should be connected to your dd-wrt router.  OpenVPN is probably not running but do “ps” to list all running processes.  To check if openvpn is running, do “ps |grep open”.  If it’s not running, then check a few things.  go to your /tmp/openvpn directory.  Do you see your certs there?  The GUI should have the individual config sections as files.  Check to make sure dh2048.pem is there and that first four lines in the Additional Config that you added above actually map to real files.  If not then simply cp dh.pem dh2048.pm or change your Additional Config section to match the file name.  Also look at your /var/log/openvpn log file (you can type cat /var/log/openvpn) to see if there are any obvious errors.

Try to start it manually now.  Simply type “openvpn openvpn.conf”  If after you hit enter and you DO NOT see a new line, then it’s running.  If it immediately returns a new line, then something is still wrong and you need to look into the log file.  If it DOES NOT return a new line, you can also verify it’s running in the web gui by going to Status, OpenVPN.

Now here is the tricky part, you obviously want DD-WRT to manage starting the service so try to see if it can handle it from here (assuming you got it working via the terminal).  Ctrl-C and kill the openVPN that you had running in Terminal.  (Check Status, VPN and you should see it not running).  Now go to Services, VPN, click Disable for Open VPN, Save, Apply Settings (this should end your terminal session as the router reboots or whatever), Click Enable, Save, Apply Settings and now it should be running.  If not, continue to troubleshoot as above.  If you can’t get it to work in the GUI, then I would recommend just continue testing via Terminal to ensure you can the rest of it working.

Once you have it running, now you get to play with iptables!  In order for the .66 OpenVPN segment to see your other computers on the network, you have to setup some rules.  What does that mean?  Basically in order for traffic in the .66 segment to play with your internal computers, you need to explain how they can travel there.  This is what I used.

iptables -I INPUT 1 -p udp –dport 1194 -j ACCEPT
iptables -I FORWARD 1 –source 192.168.66.0/24 -j ACCEPT
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A FORWARD -o tun+ -j ACCEPT

Let me explain what they do:

The first line ensures that your firewall does not block access to your router.  We want to make sure UDP port 1194 is open.  If it’s not open then the VPN will never work!  To test if the port is open, you’ll need to connect from somewhere remote (after you run these commands obviously). Use nc to do this e.g. nc -vnzu 1.1.1.1 1194  Change 1.1.1.1 to your public ip address.  the -u option is for UDP.  If you ever wanted to test another port under TCP, just remove the u in -nvnzu  Very useful!

The next three lines all allow the forwarding of those requests from your VPN into your local network.

So let’s test.  Assuming OpenVPN is running, connect via terminal to your router again.  check opevpn is running (ps |grep open).  Ideally you check to see if your port is closed by running nc command above.  Now copy and paste those iptables lines into terminal and run them all.  Check again and nc should report the port is open.  If openVPN is not running, copy and paste the iptables commands, verify you see them using iptables –list and then start openvpn openvpn.conf  That terminal session is basically locked running openvpn.  You can always start another terminal session that is looking at the log file too.

If that worked, fantastic, now you just have to get the client configured and this isn’t easy either!

Client Configuration

It was really nice of Apple to remove PPTP support, but NOT add native OpenVPN in the Settings !  You’ll have to download a VPN client for your iPhone so go to the app store and download OpenVPN.  Now this is the pain in the butt part, you have to copy your client certs (NOT SERVER!) onto your iPhone.  Of course you can’t magically drag files onto your phone so you have to use our friend iTunes.  To do this, connect your phone to iTunes (via cable I guess).  Click on your device, click on Apps, scroll DOWN to the bottom until you see a list of apps that allow you to copy files.  (This is not the section above where you can rearrange your app icons).  Click on OpenVPN app and drag the 4 clients files into the right hand side Documents section  (four files = ca.crt, client1.crt, client1.key, client1.opvn).  Sync.  If you can’t find where to copy the files, SCROLL DOWN to the bottom of the Apps section of your phone.

Open OpenVPN on your iPhone and you should see a configuration for the public ip address of your OpenVPN server.  If you screw up, you can delete it by touching on the ip address, upper right hand corner touch Delete, touch red circle on the left with the line through it (very bad UI experience).  Before you connect to your VPN, ensure to turn off Wifi on your iPhone otherwise it’s not a very good test (I don’t think it will work anyway!)  To test connected to your OpenVPN, slide the button to the right (again very bad UI design).  You should see it say Waiting for server, Connecting, Connected!  Down below in VPN IPv4 section you should see the IP address that was assigned.  For me it’s 192.169.66.X  If you are not connected, then touch the “Connecting” section of the app to read the log.  Initially when I set it up, there was a time difference between where I setup the cert and GMT.  I had to wait 5 hours for it to be resolved.  There is a way to fix it, but since I was already going to sleep the problem worked itself out the next day ;-).  To manually check this look at your clien1.crt file.  There is a Validity section which helps you understand when the cert STARTS working and when it ends (in 10 years).

If all that worked, now you can see if you can access anything in your home network.  You can try to use VNC Lite to connect to a home computer or download the Ping app from the app store and ensure you can see your local network.  I assume there is something you want to VPN in for so test it.  You can also test to ensure you are connected by pinging the IP address of your phone. For example, from a computer on my local network,  ping the IP address that your phone was assigned. e.g. ping 192.168.66.2

If that all works, you’re almost there.  If you reboot or change your configuration on your router, your iptables commands get lost.  To make them permanent, go to the dd-wrt gui, click administration, commands.  Copy and paste those iptables runs and click Run Commands and to save permanently click “Save Firewall”.  That’s it!

Phew.  I hope that’s it and you get this working.  The certs are tricky as well as the routing and firewall rules.  All this info was build from various sources.  Here are those sources just in case there are some variations to your setup.  Good luck!

Forum question on getting it working

Creating client and server keys using EasyRSA

Having trouble copying files to OpenVPN iOS App from ITunes

Additional Info to setup manually

OpenVPN client for Mac