{"id":1758,"date":"2014-02-16T23:06:18","date_gmt":"2014-02-16T21:06:18","guid":{"rendered":"http:\/\/raftaman.net\/?p=1758"},"modified":"2021-05-15T11:46:37","modified_gmt":"2021-05-15T09:46:37","slug":"how-to-set-up-a-basic-openvpn-bridging-server","status":"publish","type":"post","link":"https:\/\/possiblelossofprecision.net\/?p=1758","title":{"rendered":"How to set up a basic OpenVPN bridging server"},"content":{"rendered":"<p>Beside the official <a href=\"http:\/\/openvpn.net\/index.php\/open-source\/documentation\/howto.html\">OpenVPN documentation<\/a> there&#8217;s a vast number of howtos and guides out there, that&#8217;ll tell you how to set up an <a href=\"http:\/\/openvpn.net\">OpenVPN<\/a> server. Unfortunately, most of these use a tunneling setup including some sort of router and packet filter. If you want to transport non-IP based traffic and can accept the increased broadcast overhead and poor scalability, you need to setup an <a href=\"http:\/\/openvpn.net\/bridge.html\">OpenVPN bridge<\/a>.<\/p>\n<p><!--more--><\/p>\n<h2>Installing the packages<\/h2>\n<p>Since OpenVPN is one of the most popular VPN solutions, we don&#8217;t have to worry about compiling the software ourselves. Fedora ships a pre-packaged version and even offers a bunch of scripts (<code>easy-rsa<\/code>) that greatly simplify key-handling.<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nyum install openvpn easy-rsa\r\n<\/pre>\n<h2>Generating the keys<\/h2>\n<p>Before we can configure the actual OpenVPN server, we have to deal with key management. There are a couple of ways to authenticate with an OpenVPN server instance, but the best choice is usually an X.509 certificate and pre-shared keys.<\/p>\n<p>The first step is to set some environment variables (KEY_COUNTRY, KEY_PROVINCE, KEY_CITY, KEY_ORG, KEY_EMAIL), which are found at the bottom of <code>\/usr\/share\/easy-rsa\/2.0\/vars<\/code><\/p>\n<pre class=\"brush: plain; title: \/usr\/share\/easy-rsa\/2.0\/vars; notranslate\" title=\"\/usr\/share\/easy-rsa\/2.0\/vars\">\r\n&#x5B;...]\r\nexport KEY_COUNTRY=&quot;US&quot;\r\nexport KEY_PROVINCE=&quot;CA&quot;\r\nexport KEY_CITY=&quot;City&quot;\r\nexport KEY_ORG=&quot;Company&quot;\r\nexport KEY_EMAIL=mail@example.org\r\nexport KEY_CN=server-CA\r\nexport KEY_NAME=server-CA\r\nexport KEY_OU=&quot;&quot;\r\n<\/pre>\n<p>Next, we can create our Certificate Authority key<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n# cd \/usr\/share\/openvpn\/easy-rsa\/2.0\/\r\n# source .\/vars \r\nNOTE: If you run .\/clean-all, I will be doing a rm -rf on \/usr\/share\/easy-rsa\/2.0\/keys\r\n# .\/clean-all\r\n# .\/build-ca \r\nGenerating a 1024 bit RSA private key\r\n&#x5B;...]\r\n<\/pre>\n<p>and generate the server key and <a href=\"http:\/\/en.wikipedia.org\/wiki\/Diffie%E2%80%93Hellman_key_exchange\">Diffie-Hellman<\/a> key afterwards.<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n# .\/build-key-server server\r\nGenerating a 1024 bit RSA private key\r\n&#x5B;...]\r\n\r\n# .\/build-dh\r\nGenerating DH parameters, 1024 bit long safe prime, generator 2\r\nThis is going to take a long time\r\n&#x5B;...]\r\n<\/pre>\n<p>Finally, we need to build a certificate and key for each client with a unique common name. OpenVPN assigns IP addresses by common name, so non-unique names would result in conflicting IP addresses.<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n# .\/build-key client\r\nGenerating a 1024 bit RSA private key\r\n..............++++++\r\n...........................................++++++\r\nwriting new private key to 'client.key'\r\n&#x5B;...]\r\n<\/pre>\n<p>The only thing left to do is copying the keys to the OpenVPN configuration directory and adjusting the permissions accordingly.<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n# cp -a keys\/ \/etc\/openvpn\/\r\n# chmod 755 \/etc\/openvpn\/keys\/\r\n<\/pre>\n<h2>Setting up the server<\/h2>\n<p>To set up the server, generate a configuration file in <code>\/etc\/openvpn<\/code> with the following content:<\/p>\n<pre class=\"brush: plain; title: \/etc\/openvpn\/server.conf; notranslate\" title=\"\/etc\/openvpn\/server.conf\">\r\nport 1194\r\nproto udp\r\nserver-bridge 192.168.8.10 255.255.255.0 192.168.8.20 192.168.8.30\r\ndev tap\r\nca keys\/ca.crt\r\ncert keys\/server.crt\r\nkey keys\/server.key \r\ndh keys\/dh1024.pem\r\nup bridge-start\r\ndown bridge-stop\r\nkeepalive 10 600\r\ncomp-lzo\r\npersist-key\r\npersist-tun\r\nverb 3\r\nmute 20\r\nstatus openvpn-status.log\r\nscript-security 2\r\n\r\n# The server doesn't need privileges\r\nuser openvpn\r\ngroup openvpn\r\n<\/pre>\n<p>For a full list of options have a look at the <a href=\"https:\/\/community.openvpn.net\/openvpn\/wiki\/Openvpn23ManPage\">OpenVPN manpage<\/a>.<\/p>\n<p>To start and stop the bridge device, the OpenVPN package supplies two simple scripts. Copy them into the OpenVPN config directory<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n# cp \/usr\/share\/doc\/openvpn\/sample\/sample-scripts\/bridge-start \/etc\/openvpn\/\r\n# cp \/usr\/share\/doc\/openvpn\/sample\/sample-scripts\/bridge-stop \/etc\/openvpn\/\r\n<\/pre>\n<p>You have to alter both scripts slightly to match your configuration<\/p>\n<pre class=\"brush: plain; highlight: [8,19,20,21,22,23,43,44]; title: \/etc\/openvpn\/bridge-start; notranslate\" title=\"\/etc\/openvpn\/bridge-start\">\r\n#!\/bin\/sh\r\n\r\n#################################\r\n# Set up Ethernet bridge on Linux\r\n# Requires: bridge-utils\r\n#################################\r\n\r\nPATH=\/usr\/local\/sbin:\/usr\/local\/bin:\/usr\/sbin:\/usr\/bin:$PATH\r\n\r\n# Define Bridge Interface\r\nbr=&quot;br0&quot;\r\n\r\n# Define list of TAP interfaces to be bridged,\r\n# for example tap=&quot;tap0 tap1 tap2&quot;.\r\ntap=&quot;tap0 tap1&quot;\r\n\r\n# Define physical ethernet interface to be bridged\r\n# with TAP interface(s) above.\r\neth=&quot;eth0&quot;\r\neth_ip=&quot;192.168.8.10&quot;\r\neth_netmask=&quot;255.255.255.0&quot;\r\neth_broadcast=&quot;192.168.8.255&quot;\r\neth_gateway=&quot;192.168.8.254&quot;\r\n\r\nfor t in $tap; do\r\n    openvpn --mktun --dev $t\r\ndone\r\n\r\nbrctl addbr $br\r\nbrctl addif $br $eth\r\n\r\nfor t in $tap; do\r\n    brctl addif $br $t\r\ndone\r\n\r\nfor t in $tap; do\r\n    ifconfig $t 0.0.0.0 promisc up\r\ndone\r\n\r\nifconfig $eth 0.0.0.0 promisc up\r\n\r\nifconfig $br $eth_ip netmask $eth_netmask broadcast $eth_broadcast\r\nsleep 1\r\nroute add default gw $eth_gateway\r\n<\/pre>\n<pre class=\"brush: plain; highlight: [7]; title: \/etc\/openvpn\/bridge-stop; notranslate\" title=\"\/etc\/openvpn\/bridge-stop\">\r\n#!\/bin\/sh\r\n\r\n####################################\r\n# Tear Down Ethernet bridge on Linux\r\n####################################\r\n\r\nPATH=\/usr\/local\/sbin:\/usr\/local\/bin:\/usr\/sbin:\/usr\/bin:$PATH\r\n\r\n# Define Bridge Interface\r\nbr=&quot;br0&quot;\r\n\r\n# Define list of TAP interfaces to be bridged together\r\ntap=&quot;tap0 tap1&quot;\r\n\r\nifconfig $br down\r\nbrctl delbr $br\r\n\r\nfor t in $tap; do\r\n    openvpn --rmtun --dev $t\r\ndone\r\n<\/pre>\n<p>Note that you have to change the <strong><tt>PATH<\/tt> variable<\/strong> in order for the script to work with Fedora 20. You&#8217;ll also need to add a <strong>single <tt>tap<\/tt> device for every client<\/strong> and might want to <strong>add a default route<\/strong> after enabling the bridge.<\/p>\n<p>The fact that OpenVPN supports multiple servers and every deamon requires a single configuration file collides with the <code>systemd<\/code> way of doing things. This is simply something that is not supported by <code>systemd<\/code> out of the box. To enable and start the OpenVPN service, run<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n# ln -s \/lib\/systemd\/system\/openvpn\\@.service \/etc\/systemd\/system\/multi-user.target.wants\/openvpn\\@server.service \r\n# systemctl -f enable openvpn@server.service \r\n# systemctl start openvpn@server.service \r\n<\/pre>\n<p>Note that the name of the service (&#8220;openvpn@server.service&#8221;) corresponds with the name of the configuration file in <code>\/etc\/openvpn<\/code><\/p>\n<h2>Watching the status log<\/h2>\n<p>You can see who is currently connected to your OpenVPN server, by observing the <code>openvpn-status.log<\/code> file.<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n# watch -n 1 cat \/etc\/openvpn\/openvpn-status.log\r\n<\/pre>\n<p>Resources:<br \/>\n<a href=\"https:\/\/fedoraproject.org\/wiki\/Openvpn\">https:\/\/fedoraproject.org\/wiki\/Openvpn<\/a><br \/>\n<a href=\"https:\/\/wiki.archlinux.org\/index.php\/Create_a_Public_Key_Infrastructure_Using_the_easy-rsa_Scripts\">https:\/\/wiki.archlinux.org\/index.php\/Create_a_Public_Key_Infrastructure_Using_the_easy-rsa_Scripts<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Beside the official OpenVPN documentation there&#8217;s a vast number of howtos and guides out there, that&#8217;ll tell you how to set up an OpenVPN server. Unfortunately, most of these use a tunneling setup including some sort of router and packet filter. If you want to transport non-IP based traffic and can accept the increased broadcast overhead and poor scalability, you&#8230; <a href=\"https:\/\/possiblelossofprecision.net\/?p=1758\">Read more &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[7,66],"class_list":["post-1758","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-fedora","tag-openvpn"],"_links":{"self":[{"href":"https:\/\/possiblelossofprecision.net\/index.php?rest_route=\/wp\/v2\/posts\/1758","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/possiblelossofprecision.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/possiblelossofprecision.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/possiblelossofprecision.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/possiblelossofprecision.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1758"}],"version-history":[{"count":16,"href":"https:\/\/possiblelossofprecision.net\/index.php?rest_route=\/wp\/v2\/posts\/1758\/revisions"}],"predecessor-version":[{"id":2193,"href":"https:\/\/possiblelossofprecision.net\/index.php?rest_route=\/wp\/v2\/posts\/1758\/revisions\/2193"}],"wp:attachment":[{"href":"https:\/\/possiblelossofprecision.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1758"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/possiblelossofprecision.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1758"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/possiblelossofprecision.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1758"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}