|
|
On Fri, 2005-12-30 at 14:21 +0100, Markus Feilner wrote: > Hello List, > I am writing on a book on OpenVPN (almost ready...) and I would appreciate > everybody who could send me (or post to this list) advanced configuration > examples. > I have several examples like certificate-based authentication with > client-specific options (client config dir) and revoke list, advanced > firewall issues (masquerading the tunnel etc.), and tap-devices with DHCP > configuration etc. > Nevertheless I would love to get input or ideas of typical or non-standard > openvpn configurations that somebody has implemented, like e.g. examples on > authentication scripts or use of sophisticated skripts with openvpn. > Thanks for the input! > Of course any private mail will be answered, too! > :-) > We are brand new to OpenVPN and so are still exploring the possibilities. However, over the weekend we successfully integrated OpenVPN into an ISCS environment (http://iscs.sourceforge.net) for highly secure, large scale, remote access environments. It has magically solved almost all the remaining obstacles we faced and is an ideal entry point into an ISCS network. First, I'll describe the practical implications of this synthesis and then a little about how we did it. ISCS enables us to manageably and affordably extend perimeter style network security into the interior of the network whether between WAN connected offices or in a core switch. It does so with remarkable granularity, e.g., a limited number of superusers could have access to all systems, all users of an entire ISP could have access to five services of the public trouble ticketing system or financial, executive and sales departments could have access to the sales data while only finance and executive have access to the financial data. It also moves the access control decision from the gateway protecting the resource to the gateway protecting the accessor (user). The result is that we can use extended and out-of-band forms of user authentication (e.g., X.509 certificates, RADIUS, Active Directory, LDAP, SecureID tokens) throughout the entire WAN without resorting to spoofable, virtual IP addresses or requiring access to each individual gateway. Let me illustrate practically. Let's say we have an ISCS policy where anyone with a X.509 DER_ASN.1_DN where O=MyCompany and OU=Executive has access to Strategic Market Data, R&D and Financial Data. Financial Data is in five different services in New York, R&D uses 18 services spread between Frankfurt and Bangalore while Strategic Marketing uses eight services between Paris, New York and Tokyo. Non OpenVPN/ISCS systems would handle this either of two ways. 1) Use the extended authentication credentials on each of the gateways protecting New York, Paris, Tokyo, Bangalore and Frankfurt - a management nightmare to manage all those separate connections for every user. 2) Connect to a centralized RAS gateway with the extended credentials and then be assigned a virtual IP address. Since the access control decisions are made on the gateways which protect the resources, they must make their decisions based upon the IP address and not the extended credentials. That relegates us to spoofable, IP address security. With OpenVPN/ISCS, a user can connect to any gateway and present their extended credentials. They only need to connect to one gateway. Since all ISCS systems are "loosely aware" of the others and the access control decision is made on the gateway protecting the accessor and not the resource, the user sends their packets to the OpenVPN gateway. The OpenVPN gateway makes an access control decision based upon their extended authentication credentials and then forwards or drops the packet appropriately. All access control decisions throughout the entire WAN are made based upon the extended user credentials but the user can connect to just one gateway. How do we do it? The first step is organizing the access control rules. Although ISCS is not finished, we have used it in limited production. A recent typical client has roughly one dozen sites in the US and Europe with roughly thirty servers. To implement granular, interior security using typical monolithic firewall rules (e.g., iptables -A FORWARD -s 10.1.1.0/24 -d 10.1.2.5 -p tcp --dport 80 -j ACCEPT) would have required roughly 80,000 rules in this environment. With ISCS, we use the same firewall tools like iptables but use them differently. We create modular rather than monolithic rules which evaluate source separately from destination and then only evaluate the pertinent rules. Consequently, the rule set reduces to about 8000 rules of which only a small subset need to be traversed by any one packet. That's still too complicated so we then "magically" eliminate order dependence to reduce human error. Finally, we highly abstract the rule sets into high level policies -- about 15 in this case to describe the entire security environment. As a result, the entire security configuration can be set up in a couple of hours of dragging and dropping and most of that is just defining the accessors (users) and resources. The actual policies took less than half an hour to implement. The modularity and abstraction are achieved through a judicious use of user defined chains. Thus, the OpenVPN/ISCS combination works with any firewall that supports user defined chains such as iptables. The key, and the part that OpenVPN does so well, is to channel the remote access users into the appropriate chain based upon their extended credentials when they connect. Here is an example of the client-connect script for X.509 DN based access. The client-disconnect script is almost identical: #!/bin/sh IF_TYPE=tun+ PEER_ADDR=$ifconfig_pool_remote_ip PEER_ID=$tls_id_0 PEER_CA=$tls_id_1 PEPDIR=/etc/PEP . $PEPDIR/DNRead A exit 0 The magic is in the DNRead script. This script is a little more complicated. To fully understand what it is doing, one must understand the chaining structure of ISCS. This is described in the "PEP Packet Flow" document in the devel-docs section of the ISCS CVS on SourceForge. Once an also find a fully commented version of the script in the PEP directory of the ISCS CVS. #!/bin/sh # # ISCS DEVELOPMENT TEAM: DO NOT DIRECTLY EDIT THIS FILE. EDIT DNRead.comments, STRIP THE COMMENTS AND SAVE THE STRIPPED VERSION AS DNRead # # Copyright (C) 2003 - 2005 John A. Sullivan III # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # e-mail: jsullivan@xxxxxxxxxxxxxxxxxxx if [[ "$1" != [AD] ]] # make sure we've passed the needed parameters from X509updown then echo "Needed action parameter not passed to iptables - aborting connection!!!!!" exit 13 fi DelimitedID="$PEER_ID," # We need to add a , on the end or the match test for the last field will not work case $1 in "A" ) iptables -I VPN_ALLOW 1 -s "$PEER_ADDR" -j RETURN ;; "D" ) iptables -D VPN_ALLOW -s "$PEER_ADDR" -j RETURN ;; * ) echo "Needed action parameter not passed to iptables - aborting connection!!!!!" exit 13 ;; esac AccessGroups="" IFSORIG=$IFS if [ -s $PEPDIR/DNListDENY ] then IFS=";" while read DN CA GROUP do if [ $PEER_CA != $CA ]; then continue; fi # No need to process if this ID is from a different CA match="true" OIFS="$IFS" IFS=",/" # WE MAY NEED TO ADD / AS A DELIMETER SINCE IT IS A LEGAL X.509 FIELD DELIMETER for field in $DN do if [ "${field##*=}" == "*" ]; then continue; fi # Don't test if the field is set to * if [ "${DelimitedID/"$field"\//}" == "${DelimitedID}" ] then match="false" break fi done IFS="$OIFS" if [ "$match" != "false" ];then AccessGroups="$GROUP; $AccessGroups";fi # Build the AccessGroups string if we didn't have a mismatch done < $PEPDIR/DNListDENY # IFS=$IFSORIG until [ "$AccessGroups" == "${AccessGroups#;}" ] do AccessGroups="${AccessGroups#;}" done IFS=";" declare -a group group=($AccessGroups) # Create an array to hold the individual elements of the string while [ "${group[0]}" != "" ] do count=2 countmax=${#group[@]} while [ $count -lt $countmax ] do if [ ${group[1]} == ${group[$((count+1))]} ] # If it is a duplicate then unset group[$count] unset group[$((count+1))] fi let "count+=2" done if [ "${group[0]}" != "" ] then iptables -$1 ACCESS_GROUPS_DENY -s "$PEER_ADDR" -j "${group[1]}_DENY" # We will call this from updown with either a A or D unset group[0] unset group[1] fi group=(${group[@]}) done fi AccessGroups="" if [ -s $PEPDIR/DNList ] then IFS=";" while read DN CA GROUP do if [ $PEER_CA != $CA ]; then continue; fi # No need to process if this ID is from a different CA match="true" OIFS="$IFS" IFS=",/" # WE MAY NEED TO ADD / AS A DELIMETER SINCE IT IS A LEGAL X.509 FIELD DELIMETER for field in $DN do if [ "${field##*=}" == "*" ]; then continue; fi # Don't test if the field is set to * if [ "${DelimitedID/"$field"\//}" == "${DelimitedID}" ] then match="false" break fi done IFS="$OIFS" if [ "$match" != "false" ];then AccessGroups="$GROUP; $AccessGroups";fi # Build the AccessGroups string if we didn't have a mismatch done < $PEPDIR/DNList IFS=$IFSORIG until [ "$AccessGroups" == "${AccessGroups#;}" ] do AccessGroups="${AccessGroups#;}" # Eliminate leading ; caused by done IFS=";" group=($AccessGroups) while [ "${group[0]}" != "" ] do count=2 countmax=${#group[@]} while [ $count -lt $countmax ] do if [ ${group[1]} == ${group[$((count+1))]} ] || [ ${group[0]} != ${group[0]#${group[$count]}\/} ] # If it is a duplicate or hierar then unset group[$count] unset group[$((count+1))] else if [ ${group[$count]} != ${group[$count]#${group[0]}\/} ] #If count is a child of 0, that is 0 is a hierarchical duplicate then unset group[0] unset group[1] break fi fi let "count+=2" done if [ "${group[0]}" != "" ] # Am I here because I am hierarchically redundant and broke the loop or because I am hierarchically unique then iptables -$1 ACCESS_GROUPS -s "$PEER_ADDR" -i $IF_TYPE -j "${group[1]}" unset group[0] unset group[1] fi group=(${group[@]}) done fi IFS=$IFSORIG Here is a sample of a simple DNList file to associate the DNs with the Access Groups: O=Atlas,OU=Eng;/C=US/O=Atlas/OU=PKI/CN=AtlasTestCA;Eng;Eng We are very interested in pursuing this further. For example, the combination of iptables, openwan, OpenVPN and ISCS gives us something more powerful that the most expensive commercial systems available anywhere at any price and with the best of IPSec and SSL VPNs. This is potentially more powerful and more manageable than any $80,000 device from F5 or Aventail and more flexible and easier to manage than a six figure Solsoft or CheckPoint Provider1 system. However, it is a huge undertaking. If anyone is interested in taking this further either as pure open source or as a commercial product using open source technologies, please let me know. I look forward to seeing the book - John -- John A. Sullivan III Open Source Development Corporation +1 207-985-7880 jsullivan@xxxxxxxxxxxxxxxxxxx Financially sustainable open source development http://www.opensourcedevel.com ____________________________________________ Openvpn-users mailing list Openvpn-users@xxxxxxxxxxxxxxxxxxxxx https://lists.sourceforge.net/lists/listinfo/openvpn-users Warning: require_once(../../../archive_common.php) [function.require-once]: failed to open stream: No such file or directory in /home/openvpn/domains/openvpn.net/public_html/archive/openvpn-users/2006-01/msg00023.html on line 509 Fatal error: require_once() [function.require]: Failed opening required '../../../archive_common.php' (include_path='/usr/local/lib/php') in /home/openvpn/domains/openvpn.net/public_html/archive/openvpn-users/2006-01/msg00023.html on line 509 |