Setup OpenVPN on Centos

Occasionally when I’m out I’d like to be able to remote into my machine back at home. In the past I have opened up a random port, moved RDP to it, and called it good. I don’t really trust that level of security and I feel dirty when I get home. I’d like another layer there and I know OpenVPN is a proven technology. So I’m going to spend some time this weekend setting up OpenVPN on a CentOS machine that I have laying around. I’m hopeful that will allow me to VPN into my home network and then access my Windows machine over RDP. Let’s go!

While my CentOS box is updating I’m surfing the web for some instructions. I use this machine as a build, test, and general development server. The following command tells me I’m running CentOS release 6.6 (Final).

$cat /etc/issue

A quick yum search tells me that there is no ‘openvpn’ in the base repo’s so I’m going to enable EPEL. I’m pretty sure I had it setup once already, but I recently had to rebuild the server after a hard drive crash. Oh, that reminds me, I’m logged in as root because I haven’t setup extra accounts yet. I’ll need to fix that before vacation.

$yum search openvpn
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.easynews.com
* centosplus: repos.lax.quadranet.com
* extras: mirror.san.fastserv.com
* updates: mirror.us.oneandone.net
Warning: No matches found for: openvpn

I’m skimming sites for OpenVPN config info. This one mentions the EPEL and setting up keys with ‘easy-rsa’. What the heck, can’t I setup keys with some funky openssl command? I’ll keep digging… here’s ‘easy-rsa’ again and it looks like they’re building rpm’s by hand. No thanks.

Ok, yum update finished so it’s time to install EPEL. Here’s the command I used to install this extra repo. I also follow it up by disabling it by default. Whenever I need it or want to run an update I tack on --enablerepo=. That keeps me from installing or updating something from the EPEL on accident. Don’t ask me where I got the command from, hopefully it still works.

$rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm

Oh, it’s already installed and ‘/etc/yum.repos.d/epel.repo’ says it’s disabled by default.

cat /etc/yum.repos.d/epel.repo
[epel]
name=Extra Packages for Enterprise Linux 6 - $basearch
#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch
failovermethod=priority
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
...

Now yum reports that it found openvpn. Here goes nothing.

$yum --enablerepo=epel search openvpn
$yum --enablerepo=epel install openvpn

The easy part is over and the fun begins. Now what? chkconfig --list tells me it is installed and not running yet. The post mentioned above tells me that there are sample config files and I see them. There’s nothing in ls /etc/openvpn so I guess that’s what I need to do.

$'ls /usr/share/doc/openvpn-2.3.2/sample/sample-config-files/'
client.conf office.up roadwarrior-server.conf tls-office.conf
firewall.sh openvpn-shutdown.sh server.conf xinetd-client-config
home.up openvpn-startup.sh static-home.conf xinetd-server-config
loopback-client README static-office.conf
loopback-server roadwarrior-client.conf tls-home.conf

I’m going to copy server.conf over to /etc/openvpn, but wait what’s the init.d file say for config?

$cat /etc/init.d/openvpn

I see nothing about a config file. Oh wait, never mind. It loops through the /etc/openvpn directory to find all .conf files. That seems a little sketchy but what do I know about init.d files? Guess I’ll copy it over and edit. I don’t know why I still type vim instead of vi.

$cp /usr/share/doc/openvpn-2.3.2/sample/sample-config-files/server.conf /etc/openvpn/
$vim /etc/openvpn/server.conf

Steve at GRC tells me that some ISP’s block 1194 so I’m going to dump it on a random port. WhyY U NO FINISH TUTORIAL?? not, I was going to do it anyway. By the way Steve, why haven’t you finished your OpenVPN tutorial yet? Yes yes, I know proxpn sponsors Security Now.

local 192.168.1.10
port **********

Research time. What’s dev tap/tun and dev-node? Why do all of these guides have one setup a private key first? That’s gotta be the easiest part of the whole thing. Ok, dev tun it is. Server fault tells me that mobile doesn’t support dev tap. Thanks Siegfried Löffler, I believe you even though you only have one internet point (that’s more points than me anyway).

Oh fine, time to create a key. Looks like ‘easy-rsa’ is supplied by the openvpn people. Do I have to use it? Whatever, guess I’ll go for it. Oh, it’s not installed by default.

$yum --enablerepo=epel install easy-rsa

Crud, where did it install? This says to make a directory and copy the files over. They’re in that spot so I’m going to believe what the magic internet tells me.

$mkdir -p /etc/openvpn/easy-rsa/keys
$cp -rf /usr/share/easy-rsa/2.0/* /etc/openvpn/easy-rsa/
$vim /etc/openvpn/easy-rsa/vars

Well look at that, that’s exactly what ‘vars’ tells me to do anyway. Change this, it’s obviously wrong.

# These are the default values for fields
# which will be placed in the certificate.
# Don't leave any of these fields blank.
export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="me@myhost.mydomain"
export KEY_OU="MyOrganizationalUnit"

Still following for the key creation. Looks like they got it right to me. Why so many different extensions for (config, conf, cnf)? Wow, this config file is full of a bunch of stuff I don’t care about.

$cp /etc/openvpn/easy-rsa/openssl-1.0.0.cnf /etc/openvpn/easy-rsa/openssl.cnf

Magic internet site tells me to run the following. Super user tells me that source “executes the content of the file passed as argument, in the current shell.” Thanks nagul, maybe I should have researched that before blindly running the command. Weird, how the heck does ./clean-all do anything? I don’t see it in the directory… oh, duh it’s a directory.

$cd /etc/openvpn/easy-rsa/
$source ./vars
$./clean-all
$./build-ca
$./build-key-server server
$./build-key client
$./build-dh

Answer all of the nice scripts questions now please. You know what’s funny? I have done this exact process while creating a self signed cert for my server. Maybe I could do without easy-rsa? Oh well, this certainly is a lot less work. Ugh, this is taking forever.

Finally, now I have a self signed cert that I don’t have to touch for 3650 days. I’m sure I’ll forget how I generated it in that time. Ignoring that copy the files like says. After this is all over I’ll need to remember to copy the client keys to my Mac.

$cd /etc/openvpn/easy-rsa/keys/
$cp dh2048.pem ca.crt server.crt server.key /etc/openvpn/

Back to the server config file, edit and change the lines. Everyone’s using Google’s DNS servers so I may as well also. I do like OpenDNS but I’m not going to argue with three other sites that I’m following.

$vim /etc/openvpn/server.conf
dh dh2048.pem
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
user nobody
group nobody

Am I done now? It seems like there should be more to the whole process. Guess I’ll punch a hole in my router and start the service. Maybe I can connect via my Mac internally. I’m assuming I know it works if I connect and get a 10.8.x.x address since I think I saw that in a config somewhere.

$vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
$sysctl -p

Time to fire it up!

$service openvpn start
$chkconfig openvpn on

Looks good, ‘ifconfig’ gives the same output as shown here. Now don’t I need to get some sort of key to my client? I would hope this is all secured with key files. Yep, I’ll need to copy the following to my Mac.

/etc/openvpn/easy-rsa/keys/ca.crt
/etc/openvpn/easy-rsa/keys/client.cert
/etc/openvpn/easy-rsa/keys/client.key

To do that I’m going to archive them and then copy the archive over to my Mac. However you get the files to your machine is up to you. I always forget how scp works so the command is below but you’ll need to tune it for your setup.

$cd /etc/openvpn/easy-rsa/keys/
$tar -czvf client.tar.gz ca.crt client.crt client.key
$cp client.tar.gz /home/
$scp root@192.168.1.10:/home/client.tar.gz ~/Documents/client.tar.gz

I’m using Viscosity on my Mac to do the client side. It’s $9, can handle multiple profiles, and I already have it installed.

Nuts, looks like the Mac isn’t connecting. I know I can reach the server … oh poop, I choose the same port that SSH is running on. It couldn’t have even started. Interesting, checking the logs I see the following. I think I may need to correct that but I don’t really look forward to changing out my network configuration.

Nov 1 18:58:09 dev openvpn[12583]: NOTE: your local LAN uses the extremely common subnet address 192.168.0.x or 192.168.1.x. Be aware that this might create routing conflicts if you connect to the VPN server from public locations such as internet cafes that use the same subnet.

I see little else in the logs and ‘service openvpn restart’ didn’t error while shutting down the service. Just in case I’m going to move the port and open a hole in the firewall. Oh, hah, SSH is using tcp over my port and openssh is setup to use udp. I think I just need to poke the udp hole in my firewall for that port. I’ll try that instead.

MONEY! Yes! Now to poke a hole in my external firewall. I’ll port forward the same udp port to my server at 192.168.1.10.

Now I’m not sure how to test this other than from some remote location. It all appears to be working correctly. I know I can reach my server and connect to it but I have no idea if my traffic can hop from my server to my workstation. I enabled Remote Desktop and poked a hole through Windows firewall for port 3389. I also added my user as a Remote Desktop User because I don’t run as admin.

Network Topology - Produced with Dia Diagram Editor
Network Topology – Produced with Dia Diagram Editor

Oh, the internet tells me I can setup a subnet to test. That makes sense but I’m not sure that I can do that with my router. Maybe I can put my wireless router on a different subnet? Nope, not supported. I have a spare router around here somewhere. Oh, wait my cable modem has a router attached. I can jack into that and attempt to VPN into my second internal network. I’m running two because I don’t really trust this COX router.

The subnet that my OpenVPN server lives on is 192.168.1.X and the subnet that my Mac and internal router are now on is 192.168.0.X. Traffic cannot flow from 192.168.0 to 192.168.1 without the VPN working. I’m excited, fire it up! HAHAHA, IT CONNECTED!

Bad news, I cannot connect to my internal Windows box while connected to OpenVPN. I am connected though as I see tun0 with an IP of 10.8.0.6. Traffic is absolutely flowing but I think it’s stuck at the server. I also see ‘Nov 1 20:11:46 dev openvpn[12663]: 192.168.0.11’ in the logs which is the IP I’m connecting from. Time to research.

Oh, neat. I ran iptables -F now my pings are coming through. Perhaps it was working and my firewall rules were just dropping ping packets. Nope, something is still blocking. I can now ping my Windows machine but RDP doesn’t seem to be working. I’m going to install Wireshark on my Windows machine to see if packets are coming in.

What??? The packets are hitting the Windows machine. I can see them in Wireshark “Transmission Control Protocol, Src Port: 59778 (59778), Dst Port: 3389 (3389), Seq: 0, Len: 0”. Do I not have Windows Firewall setup correctly? Windows Firewall shows TCP/UDP 3389 is allowed in. I did change the port that RDP is listening to a little while ago. Maybe that service needs a reboot. That was it, after restarting all “Remote Destop *” services RDP is letting me in now.

I would rather not run without firewall rules so I’ll do the opposite of ‘iptables -F’ now. Part of the trouble is my firewall rules are really agressive. Only certain ports are allowed in and out. I’ll drop all of the outbound rules because OpenVPN will be opening random connections when connecting to my LAN.

Got it! Thanks to Bebop here I was able to get the correct settings for iptables. The major changes I made are below.

iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 10.8.0.0/24 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

There are a few cleanup tasks that I want to do next. First, I want some sort of password added to my key. Second, I need some sort of dynamic dns setup because my public IP will change eventually. Finally, I would love to have Google Authenticator setup to handle two factor auth. It’s getting late so I’m going to save those tasks for another day.

Leave a Reply

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