http://wiki.fusionpbx.com/index.php?title=Special:NewPages&feed=atom&hideredirs=1&limit=100&offset=&namespace=0&username=&tagfilter=FusionPBX - New pages [en]2024-03-29T11:17:27ZFrom FusionPBXMediaWiki 1.28.1http://wiki.fusionpbx.com/index.php?title=OpenVPNOpenVPN2020-08-04T19:53:29Z<p>Soapee01: /* SCRIPT */</p>
<hr />
<div>=Take 2=<br />
This basis comes from MacKiller on #fusionpbx. He's provisioning this one per client (not per phone). I (soapee01) have made some enhancements that help automate this, and improve security. My openvpn setup is a <b>DISTINCT SERVER.</b> I'm doing it this way so I can have several servers in differing geographic areas. In my case, I've got some bad routes from an ISP to my datacenter where Fusion lives, and I'm hoping to use OpenVPN to fix this. And also punch through NAT, improve security, etc.<br />
==Installation==<br />
<b>These instructions are for Debian 9 (openvpn version 2.4.0) and are known to work with the following phones/firmware</b><br />
===Working Phones===<br />
*Yealink W60B 77.83.0.85<br />
*Yealink SIP-T54W 96.85.0.24<br />
*Yealink SIP-T46S 66.84.0.90<br />
*Yealink SIP-T29G 46.83.0.126<br />
*Yealink SIP-T42S 66.85.0.5<br />
*Yealink SIP-T46G<br />
**28.83.0.120 <br />
**28.73.0.50<br />
<br />
===Phones with Issues===<br />
*put a list here...<br />
<br />
===Install Packages===<br />
Install openvpn<br />
apt install -y openvpn easy-rsa<br />
===EasyRSA===<br />
====Edit Vars====<br />
cd /usr/share/easy-rsa<br />
vim vars<br />
Change the following variables to match<br />
<pre><br />
export KEY_COUNTRY="US"<br />
export KEY_PROVINCE="YourState (two letters, eg TX)"<br />
export KEY_CITY="YourCity"<br />
export KEY_ORG="Your Company"<br />
export KEY_EMAIL="your@email.com"<br />
export KEY_OU="phones"<br />
#export KEY_SIZE=2048<br />
export KEY_SIZE=1024<br />
#export KEY_DIR="$EASY_RSA/keys"<br />
export KEY_DIR="/var/centralconfig/openvpn/keys"<br />
</pre><br />
<br />
You'll need to symlink the openssl.cnf file. It's poorly documented.<br />
ln -s openssl-1.0.0.cnf openssl.cnf<br />
edit it.<br />
vim openssl.cnf<br />
We're going to change the certificate generation algorithm. <b>This makes thinks less secure, but it is what yealink requires to work.</b> The change needs to happen in two places<br />
#CA DEFAULT<br />
#REQ<br />
#default_md = sha256 # use public key default MD<br />
default_md = sha1 # use public key default MD<br />
<br />
====Build the Server Certs====<br />
cd /usr/share/easy-rsa<br />
source ./vars<br />
./clean-all<br />
./build-ca<br />
Answer all of the questions<br />
./build-key-server server<br />
Answer all of the questions<br />
./build-key phone1<br />
./build-dh<br />
===Config OpenVPN Server===<br />
gunzip /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz<br />
cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf /var/centralconfig/openvpn/server.conf<br />
nano /var/centralconfig/openvpn/server.conf<br />
<br />
Here's what you need in the server<br />
<pre><br />
port YOUR_PORT_NUMBER<br />
proto udp<br />
dev ovpn<br />
dev-type tun<br />
ca /var/centralconfig/openvpn/keys/ca.crt<br />
cert /var/centralconfig/openvpn/keys/server.crt<br />
key /var/centralconfig/openvpn/keys/server.key <br />
dh /var/centralconfig/openvpn/keys/dh1024.pem<br />
server 10.80.0.0 255.255.0.0<br />
ifconfig-pool-persist ipp.txt<br />
#the route below may be required if openvpn lives on your<br />
#FS server, but if it does not, it registration will not<br />
#happen.<br />
#push "route YOUR_LISTENING_IP_FROM_FREESWITCH 255.255.255.255"<br />
#MAKE THIS A FULL TUNNEL INSTEAD<br />
push "redirect-gateway def1"<br />
#you might want to use the DNS provider for your domain names instead of google for faster changes<br />
push "dhcp-option DNS 8.8.8.8"<br />
client-to-client<br />
duplicate-cn<br />
keepalive 20 60<br />
comp-lzo<br />
status openvpn-status.log<br />
verb 3<br />
explicit-exit-notify 1<br />
management localhost 7505<br />
</pre><br />
<br />
ln -s /var/centralconfig/openvpn/server.conf /etc/openvpn/server.conf<br />
<br />
nano /etc/sysctl.conf<br />
change the following<br />
net.ipv4.ip_forward=1<br />
<br />
Now reboot<br />
reboot<br />
<br />
add the nat for openvpn<br />
iptables -t nat -A POSTROUTING -s 10.80.0.0/16 -o eth0 -j MASQUERADE<br />
<br />
==Phone Configuration==<br />
===SCRIPT===<br />
<b>This is now on GitHub. Grab it there.</b> This should make life much easier. It facilitates the building of vpn clients for yealink (and generic ovpn files), revokes certs, and handles all of this without a restart of openvpn.<br />
*https://github.com/jamesorose/Fusion-Scripts<br />
<br />
wget https://raw.githubusercontent.com/jamesorose/Fusion-Scripts/master/openvpngenconf.sh<br />
<br />
This script will make it trivial to add clients, revoke certificates, rebuild clients, generate yealink openvpn.tar files, etc. Here's how it's run. <br />
<pre><br />
USAGE: openvpngenconf.sh build|revoke OPTIONS<br />
---------------------------------------------<br />
<br />
build options:<br />
vpn_server_address client-name<br />
it's recommended to set client-name = phone_mac_address<br />
Build Example:<br />
openvpngenconf.sh build vpn.example.com 805ab09d345f<br />
yields a config file for yealink named /var/centralconfig/openvpn/client/805ab09d345f/openvpn.tar<br />
AND<br />
yields a config file with certs inline named /var/centralconfig/openvpn/client/805ab09d345f/vpn.example.com-805ab09d345f.ovpn<br />
<br />
<br />
revoke options:<br />
client-name<br />
Revoke Example:<br />
openvpngenconf.sh revoke Client1<br />
This will update the csr.pem file for the server and block the client from connecting.<br />
The old certificates will be moved out of the way so that you can re-generate them<br />
if you need to. Have a look in /var/centralconfig/openvpn/keys/revoked/<br />
</pre><br />
<br />
===Manual Way===<br />
mkdir -p /var/centralconfig/openvpn/client/blahclient/keys<br />
cp /var/centralconfig/openvpn/keys/ca.crt /var/centralconfig/openvpn/client/blahclient/keys/<br />
cp /var/centralconfig/openvpn/keys/blahclient.crt /var/centralconfig/openvpn/client/blahclient/keys/<br />
cp /var/centralconfig/openvpn/keys/blahclient.key /var/centralconfig/openvpn/client/blahclient/keys/<br />
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /var/centralconfig/openvpn/client/blahclient/vpn.cnf<br />
nano /var/centralconfig/openvpn/client/blahclient/vpn.cnf<br />
<br />
Then add this to the file<br />
<pre><br />
client<br />
dev tun<br />
dev-type tun<br />
proto udp<br />
remote YOUR_DNS_NAME_FOR_OPENVPN_SERVER YOUR_PORT_NUMBER<br />
setenv SERVER_Poll_TIMEOUT 4<br />
resolv-retry infinite<br />
nobind<br />
persist-key<br />
persist-tun<br />
ca /config/openvpn/keys/ca.crt<br />
cert /config/openvpn/keys/masterclient.crt<br />
key /config/openvpn/keys/masterclient.key<br />
remote-cert-tls server<br />
comp-lzo<br />
verb 3<br />
</pre><br />
<br />
===Build the tar file===<br />
tar -cvpf openvpn.tar *<br />
<br />
==Static IP for Mgmt==<br />
===Config===<br />
Basically we want to block all communication between the phones for security. By default, this is not true! We need to create a vpn client for management (eg for a windows box), and then set up some static IPs for that so we can firewall everything off.<br />
====Server Conf Changes====<br />
We MUST make some change to the server config. Mainly:<br />
*disable client-to-client<br />
**This will allow us to use iptables to decide who gets to talk to each other<br />
*Change the server directives<br />
<br />
In the above configuration we'll comment out:<br />
server 10.80.0.0 255.255.0.0<br />
and replace it with:<br />
mode server<br />
tls-server<br />
ifconfig 10.80.0.1 10.80.0.2<br />
ifconfig-pool 10.80.0.3 10.80.254.252<br />
route 10.80.0.0 255.255.255.0<br />
push "route 10.80.0.1"<br />
<br />
We're now left with a server configuration that looks like this:<br />
<pre><br />
port 1194<br />
proto udp<br />
dev ovpn<br />
dev-type tun<br />
ca /var/centralconfig/openvpn/keys/ca.crt<br />
cert /var/centralconfig/openvpn/keys/server.crt<br />
key /var/centralconfig/openvpn/keys/server.key<br />
dh /var/centralconfig/openvpn/keys/dh1024.pem<br />
#server 10.80.0.0 255.255.0.0<br />
<br />
mode server<br />
tls-server<br />
ifconfig 10.80.0.1 10.80.0.2<br />
ifconfig-pool 10.80.0.3 10.80.254.252<br />
route 10.80.0.0 255.255.255.0<br />
push "route 10.80.0.1"<br />
<br />
ifconfig-pool-persist ipp.txt<br />
client-config-dir /etc/openvpn/ccd<br />
#the route below may be required if openvpn lives on your<br />
#FS server, but if it does not, it registration will not<br />
#happen.<br />
#push "route server_ip 255.255.255.255"<br />
push "redirect-gateway def1"<br />
push "dhcp-option DNS 8.8.8.8"<br />
#client-to-client<br />
duplicate-cn<br />
keepalive 20 60<br />
comp-lzo<br />
status openvpn-status.log<br />
verb 3<br />
explicit-exit-notify 1<br />
management localhost 7505<br />
</pre><br />
<br />
====OpenVPN Client Static IP====<br />
<br />
mkdir /etc/openvpn/ccd<br />
echo "ifconfig-push 10.80.0.3 10.80.0.2" > /etc/openvpn/ccd/JamesTest<br />
<br />
<b>This doesn't work in windows. We get the following error:</b><br />
<br />
<i>There is a problem in your selection of --ifconfig endpoints [local=10.80.0.3, remote=10.80.0.2]. The local and remote VPN endpoints cannot use the first or last address within a given 255.255.255.252 subnet. This is a limitation of --dev tun when used with the TAP-WIN32 driver. Try 'openvpn --show-valid-subnets' option for more info.<br />
Exiting due to fatal error</i><br />
<br />
So it's time for some subnet calculations. :-/<br />
<br />
<br />
We've used the range: 10.80.0.0/16 for OpenVPN. However, we we'll have to divide this up into 252 subnets. This means 2 addresses (IP and gateway). The first usable would be:<br />
Gateway IP<br />
10.80.0.1 10.80.0.2<br />
10.80.0.3<br />
10.80.0.5<br />
10.80.0.7<br />
10.80.0.9 10.80.0.10<br />
<br />
so let's change the rule to:<br />
echo "ifconfig-push 10.80.0.9 10.80.0.10" > /etc/openvpn/ccd/JamesTest<br />
<br />
<br />
Now from windows we can see the following (and it connects):<br />
<br />
<b>Ifconfig</b><br />
<pre><br />
Ethernet adapter Ethernet 2:<br />
<br />
Connection-specific DNS Suffix . :<br />
IPv4 Address. . . . . . . . . . . : 10.80.0.9<br />
Subnet Mask . . . . . . . . . . . : 255.255.255.252<br />
Default Gateway . . . . . . . . . :<br />
</pre><br />
<br />
<b>Route print</b><br />
<pre><br />
IPv4 Route Table<br />
===========================================================================<br />
Active Routes:<br />
Network Destination Netmask Gateway Interface Metric<br />
0.0.0.0 0.0.0.0 192.168.1.1 192.168.1.102 25<br />
0.0.0.0 128.0.0.0 10.80.0.10 10.80.0.9 291<br />
10.80.0.1 255.255.255.255 10.80.0.10 10.80.0.9 291<br />
10.80.0.8 255.255.255.252 On-link 10.80.0.9 291<br />
10.80.0.9 255.255.255.255 On-link 10.80.0.9 291<br />
10.80.0.11 255.255.255.255 On-link 10.80.0.9 291<br />
127.0.0.0 255.0.0.0 On-link 127.0.0.1 331<br />
</pre><br />
<br />
Notice that our IP (10.80.0.9) will now be static and routed via 10.80.0.10<br />
<br />
===Firewall===<br />
Now currently our firewall is permissive. All VPN clients can connect to each other. Let's fix that.<br />
<br />
Here's the command you'll need to see the NAT rules<br />
iptables -t nat -L<br />
<br />
<br />
====Block Client <-> Client Comm====<br />
iptables -I FORWARD --src 10.80.0.0/16 --dst 10.80.0.0/16 -j DROP<br />
<br />
====Allow Managemnt IP Comm====<br />
We have to go both ways here....<br />
iptables -I FORWARD --src 10.80.0.9/16 --dst 10.80.0.0/16 -j ACCEPT<br />
iptables -I FORWARD --src 10.80.0.0/16 --dst 10.80.0.9 -j ACCEPT<br />
==Apache==<br />
Now we'd like to get those config files...<br />
<br />
apt install apache2<br />
<br />
===htaccess===<br />
add the following stanza after the last Directory tags to:<br />
<br />
vim /etc/apache2/apache2.conf<br />
<br />
#ADD for HTACCESS<br />
<Directory /var/www/><br />
Options FollowSymlinks<br />
AllowOverride All<br />
</Directory><br />
<br />
systemctl restart apache2<br />
<br />
===Turn on Directory Listings===<br />
<br />
Set your config to look like this<br />
<br />
vim /etc/apache2/sites-enabled/000-default<br />
<br />
here's the config<br />
<pre><br />
<VirtualHost *:80><br />
# The ServerName directive sets the request scheme, hostname and port that<br />
# the server uses to identify itself. This is used when creating<br />
# redirection URLs. In the context of virtual hosts, the ServerName<br />
# specifies what hostname must appear in the request's Host: header to<br />
# match this virtual host. For the default virtual host (this file) this<br />
# value is not decisive as it is used as a last resort host regardless.<br />
# However, you must set it for any further virtual host explicitly.<br />
#ServerName www.example.com<br />
<br />
ServerAdmin webmaster@localhost<br />
DocumentRoot /var/www<br />
<Directory /var/www/><br />
Options Indexes FollowSymLinks MultiViews<br />
AllowOverride AuthConfig<br />
Order allow,deny<br />
allow from all<br />
</Directory><br />
<br />
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,<br />
# error, crit, alert, emerg.<br />
# It is also possible to configure the loglevel for particular<br />
# modules, e.g.<br />
#LogLevel info ssl:warn<br />
<br />
ErrorLog ${APACHE_LOG_DIR}/error.log<br />
CustomLog ${APACHE_LOG_DIR}/access.log combined<br />
<br />
# For most configuration files from conf-available/, which are<br />
# enabled or disabled at a global level, it is possible to<br />
# include a line for only one particular virtual host. For example the<br />
# following line enables the CGI configuration for this host only<br />
# after it has been globally disabled with "a2disconf".<br />
#Include conf-available/serve-cgi-bin.conf<br />
</VirtualHost><br />
</pre><br />
===Protect the files===<br />
Add the htaccess file<br />
vim /var/www/.htaccess<br />
<br />
AuthName "Restricted Area"<br />
AuthType Basic<br />
AuthUserFile /etc/apache2/users<br />
require user FusionPBX<br />
<br />
Create the password for apache<br />
htpasswd -c /etc/apache2/users FusionPBX<br />
<br />
Link the files so we can grab them easily.<br />
cd /var/www<br />
ln -s /var/centralconfig/openvpn/client ./<br />
<br />
restart apache2<br />
systemctl restart apache2<br />
==Adding Clients==<br />
<br />
What follows below is a script I wrote to make it easier to add clients. You call it as such:<br />
openvpngenconf.sh<br />
<pre><br />
USAGE: openvpngenconf.sh build vpn_server_address client-name<br />
it's recommended to set client-name = phone_mac_address<br />
<br />
openvpngenconf.sh build vpn.example.com 805ab09d345f<br />
yields a config file for yealink named /var/centralconfig/openvpn/client/805ab09d345f/openvpn.tar<br />
AND<br />
yields a config file with certs inline named /var/centralconfig/openvpn/client/805ab09d345f/vpn.example.com-805ab09d345f.ovpn<br />
</pre><br />
<br />
<b>You DON'T HAVE TO USE A MAC ADDRESS</b> But if you want things to provision easier later, it's better to do so. Yealink CAN grab configurations via http[s] and we need some way to differentiate. Using the MAC makes sense. I also hope to automate this by grabbing entries from the FusionPBX database and calling this script.<br />
<br />
For desktop access, you'll Want to call it like<br />
openvpngenconf.sh build vpn_server_address My_Desktop_Name<br />
<br />
==TODO==<br />
*<s>certificate revocation</s><br />
**<s>hopefully without restarting openvpn.</s><br />
*Figure out why I have to manually start openvpn with:<br />
** openvpn --config /etc/openvpn/server.conf<br />
<br />
==Add a Second Server==<br />
This is pretty simple. We can set this up so that certificates and revocations are shared across multiple servers. This has a benefit of letting us reconfigure a server address for a phone, and having them automatically move to another server. We could also use this to set up a round robin based set of servers (connect randomly to servers listed in the client config) for load balancing, and provide failover for openvpn in case one of them goes down.<br />
<br />
===The procedure===<br />
apt install openvpn easy-rsa rsync<br />
<br />
====Rsync====<br />
rsync some files over<br />
<br />
from your main server copy ssh keys so we can get passwordless logins<br />
primary_server# ssh-keygen<br />
primary_server# ssh-copy-id root@secondary_server<br />
<br />
now let's rsync some files<br />
<br />
primary_server# rsync -avp --progress /usr/share/easy-rsa/ root@secondary_server:/usr/share/easy-rsa<br />
primary_server# rsync -avp --progress /var/centralconfig/openvpn/ root@secondary_server:/var/centralconfig/openvpn<br />
primary_server# rsync -avp --progress /etc/openvpn/ root@secondary_server:/etc/openvpn<br />
<br />
===Change Network===<br />
nano /etc/sysctl.conf<br />
change the following<br />
net.ipv4.ip_forward=1<br />
<br />
or you can try this sed one liner...<br />
secondary_server# sed -i -e s/\#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g /etc/sysctl.conf<br />
<br />
then reboot<br />
secondary_server# reboot<br />
<br />
====Iptables====<br />
iptables -t nat -A POSTROUTING -s 10.80.0.0/16 -o eth0 -j MASQUERADE<br />
<br />
Add your rules for your management IP<br />
iptables -I FORWARD --src 10.80.0.0/16 --dst 10.80.0.0/16 -j DROP<br />
iptables -I FORWARD --src 10.80.0.9/16 --dst 10.80.0.0/16 -j ACCEPT<br />
iptables -I FORWARD --src 10.80.0.0/16 --dst 10.80.0.9 -j ACCEPT<br />
<br />
===Finishing up===<br />
On a PC, change the openvpn client config server url to your new address. You should be able to connect.</div>Soapee01