This shows you the differences between two versions of the page.
links:openvpn [2016/04/24 13:34] jdg [Generate the openssl.cnf file using above export] |
links:openvpn [2019/03/06 07:33] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== OpenVPN config examples ====== | ||
- | |||
- | Links to local pages: | ||
- | |||
- | * [[:links:security#openvpn|Security - OpenVPN]] | ||
- | * [[:links:openvpn_notes|OpenVPN notes]] | ||
- | |||
- | These are examples of OpenVPN (http://openvpn.net/) which I have used myself frequently. | ||
- | |||
- | - [[openvpn#Static-key point-to-point mode]] | ||
- | - [[openvpn#Server TLS mode no-client-auth]] | ||
- | - [[openvpn#Server TLS mode with client-auth]] | ||
- | |||
- | |||
- | ===== Static-key point-to-point mode ===== | ||
- | |||
- | |||
- | The static-key mode is a quick-and-dirty way to build a VPN tunnel.\\ | ||
- | * it is fast if you want to make just one tunnel. | ||
- | * it would be inefficient if you want to have multiple client tunnels to connect to one server. | ||
- | |||
- | ==== static.key ==== | ||
- | |||
- | You need to create a static key with command: \\ | ||
- | |||
- | Example: | ||
- | <code> | ||
- | openvpn --genkey --secret static.key | ||
- | </code> | ||
- | |||
- | Then copy this key to both client/server. | ||
- | |||
- | ==== server-static.conf ==== | ||
- | |||
- | <code> | ||
- | # run with: openvpn --config server-static.conf | ||
- | |||
- | mode p2p # default | ||
- | proto udp # default | ||
- | dev tun # default | ||
- | port 1194 # default - server will listen on all interfaces, on this port | ||
- | dev tun | ||
- | ifconfig 10.4.0.1 10.4.0.2 # first Tunnel-IP is local, 2nd Tunnel-IP is remote | ||
- | verb 3 | ||
- | secret static.key # openvpn --genkey --secret static.key | ||
- | keepalive 10 60 | ||
- | persist-tun | ||
- | persist-key | ||
- | persist-local-ip | ||
- | comp-lzo | ||
- | </code> | ||
- | |||
- | ==== client-static.conf ==== | ||
- | |||
- | <code> | ||
- | # run with: openvpn --config client-static.conf | ||
- | |||
- | mode p2p # default | ||
- | proto udp # default | ||
- | dev tun # default | ||
- | remote 81.82.83.84 1194 # client will connect to this (server) IP + port | ||
- | ifconfig 10.4.0.2 10.4.0.1 # first Tunnel-IP is local, 2nd Tunnel-IP is remote | ||
- | verb 3 | ||
- | secret static.key | ||
- | keepalive 10 60 | ||
- | comp-lzo | ||
- | explicit-exit-notify 2 | ||
- | </code> | ||
- | |||
- | ===== Server TLS mode no-client-auth ===== | ||
- | |||
- | Pros: | ||
- | |||
- | * will accept multiple clients to one server instance | ||
- | * will automatically assign an IP address to the client from a pool \\ (like DHCP, actually more like PPP) | ||
- | * can allow communications between clients | ||
- | * is easy to setup: all clients have the same config file and cert/key | ||
- | * very secure at the cryptographic level | ||
- | |||
- | Cons: | ||
- | |||
- | * overall security is 'medium' because all clients are the same, so there is no individual authentication *1) | ||
- | * IP-addresses are allocated from a pool, so no guarantee which address is given. (possible different IP at next login). | ||
- | |||
- | //*1) this is like the WPA-PSK mode in Wireless LANs, i.e. all clients have the same key, in contrast to the WPA-mode with IEEE802.1x+RADIUS where every client has its own unique username/password or other authentication.// | ||
- | |||
- | NOTE that the client-tls.conf is the **same** for every client. | ||
- | |||
- | ==== server-tls.conf ==== | ||
- | |||
- | <code> | ||
- | # OpenVPN config "server-tls.conf" | ||
- | # | ||
- | # test using: openvpn –-config server-tls.conf | ||
- | |||
- | proto udp #default | ||
- | dev tun #default | ||
- | port 1194 #default | ||
- | management 127.0.0.1 1194 | ||
- | |||
- | # Tunnel IP-number plan: | ||
- | # network: 10.4.0.0/24 all tunnel-endpoints (TEPs) | ||
- | # IP: 10.4.0.1 server | ||
- | # IP: 10.4.0.2 server p2p address (not-used) | ||
- | # IP: 10.4.0.5 client-1 p2p address (not-used) | ||
- | # IP: 10.4.0.6 client-1 | ||
- | # IP: 10.4.0.9 client-2 p2p address (not-used) | ||
- | # IP: 10.4.0.10 client-2 | ||
- | # IP: 10.4.0.13 client-3 p2p address (not-used) | ||
- | # IP: 10.4.0.14 client-3 | ||
- | # etc... This setup allows (2^(32-24)/4)-1=63 clients | ||
- | |||
- | server 10.4.0.0 255.255.255.0 # the server Tunnel-IP will be .1 | ||
- | |||
- | # The 'server' command also established a pool of Tunnel-IPs for the clients (like DHCP) | ||
- | |||
- | #route 10.4.0.0 255.255.255.0 # this command is implicit with 'server' command | ||
- | |||
- | cd /etc/openvpn/projectname/ | ||
- | log /var/log/openvpn-projectname.log | ||
- | |||
- | ca ca.projectname.crt | ||
- | cert server.projectname.crt | ||
- | key server.projectname.key | ||
- | dh dh1024.projectname.pem | ||
- | tls-auth ta.projectname.key 0 # Use 0=server, 1=client | ||
- | |||
- | verb 3 | ||
- | keepalive 10 60 | ||
- | persist-tun | ||
- | persist-key | ||
- | persist-local-ip | ||
- | comp-lzo | ||
- | |||
- | duplicate-cn # needed if all clients use same client.crt/key | ||
- | |||
- | # Uncomment following line if you want to allow client-to-client traffic: | ||
- | # (dont use this option if you want to filter the client-to-client packets via iptables) | ||
- | #client-to-client | ||
- | |||
- | #push "route 10.4.0.0 255.255.255.0" # this is done automatically with client-to-client command (else do specify) | ||
- | |||
- | # end of "server-tls.conf" | ||
- | </code> | ||
- | |||
- | |||
- | |||
- | ==== client-tls.conf ==== | ||
- | |||
- | |||
- | <code> | ||
- | # OpenVPN config "client-tls.conf" | ||
- | # | ||
- | # run with: openvpn –config client-tls.conf | ||
- | |||
- | proto udp #default | ||
- | dev tun #default | ||
- | client | ||
- | remote 172.24.2.60 1194 | ||
- | |||
- | cd /etc/openvpn/projectname/ | ||
- | log /var/log/openvpn-projectname.log | ||
- | |||
- | ca ca.projectname.crt | ||
- | cert client.projectname.crt | ||
- | key client.projectname.key | ||
- | tls-auth ta.projectname.key 1 # Use 0=server, 1=client | ||
- | |||
- | # Verify that we are connected with the correct server: | ||
- | |||
- | tls-remote "server.projectname" | ||
- | ns-cert-type server | ||
- | |||
- | nobind | ||
- | verb 3 | ||
- | keepalive 10 60 | ||
- | comp-lzo | ||
- | explicit-exit-notify 2 | ||
- | |||
- | # end of "client-tls.conf" | ||
- | </code> | ||
- | |||
- | ==== Example certs/keys ==== | ||
- | |||
- | The "server" mode uses TLS (standardized and enhanced version of SSL) and needs X.509 certificates and keys. | ||
- | |||
- | You can use these example certs/keys, which are packaged with openvpn. | ||
- | |||
- | Use this for testing only, because everybody would have these certs/keys! | ||
- | |||
- | <code> | ||
- | cd /usr/share/doc/openvpn-2.0.9/sample-keys/ | ||
- | tmp-ca.key | ||
- | tmp-ca.crt | ||
- | dh1024.pem | ||
- | server.key | ||
- | server.crt | ||
- | client.key | ||
- | client.crt | ||
- | </code> | ||
- | |||
- | ==== Manually create certs/keys using OpenSSL ==== | ||
- | |||
- | Or generate all self with these commands (recommended!): | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | ==== Set the paramters first ==== | ||
- | |||
- | <code> | ||
- | # personalize these exports: | ||
- | |||
- | export tls_projectname="projectname" | ||
- | export tls_cert_dir="/etc/openvpn/$tls_projectname/certs/" | ||
- | export tls_ca_CN="ca.$tls_projectname" | ||
- | export tls_country="CO" | ||
- | export tls_province="Province" | ||
- | export tls_city="City" | ||
- | export tls_organization="Organisation" | ||
- | export tls_email="email@domain.com" | ||
- | export tls_server_CN="server.$tls_projectname" | ||
- | export tls_client_CN="client.$tls_projectname" | ||
- | </code> | ||
- | |||
- | |||
- | |||
- | ==== Generate the openssl.cnf file using above export ==== | ||
- | |||
- | Save this text to a file, using copy/paste: | ||
- | |||
- | <code> | ||
- | # rm -rf "$tls_cert_dir/" | ||
- | mkdir -pv "$tls_cert_dir/" | ||
- | cd "$tls_cert_dir/" | ||
- | chmod go-rwx "$tls_cert_dir/" | ||
- | touch "$tls_cert_dir/index.txt" | ||
- | echo 01 > "$tls_cert_dir/serial" | ||
- | cat > "$tls_cert_dir/generate_openssl_cnf.sh" | ||
- | </code> | ||
- | |||
- | <code> | ||
- | #!/bin/bash | ||
- | # run this script to generate "openssl.cnf" using the previously exported values | ||
- | # | ||
- | cat > openssl.cnf <<HERE | ||
- | # OpenSSL configuration file. | ||
- | # | ||
- | #generated using these variables: | ||
- | # | ||
- | #export tls_projectname="$tls_projectname" | ||
- | #export tls_cert_dir="$tls_cert_dir" | ||
- | #export tls_ca_CN="$tls_ca_CN" | ||
- | #export tls_country="$tls_country" | ||
- | #export tls_province="$tls_province" | ||
- | #export tls_city="$tls_city" | ||
- | #export tls_organization="$tls_organization" | ||
- | #export tls_email="$tls_email" | ||
- | #export tls_server_CN="$tls_server_CN" | ||
- | #export tls_client_CN="$tls_client_CN" | ||
- | # | ||
- | HOME = "$tls_cert_dir" | ||
- | RANDFILE = \$HOME/random | ||
- | oid_section = new_oids | ||
- | |||
- | [ new_oids ] | ||
- | [ ca ] | ||
- | default_ca = CA_default | ||
- | |||
- | [ CA_default ] | ||
- | dir = \$HOME | ||
- | certs = \$dir | ||
- | crl_dir = \$dir | ||
- | database = \$dir/index.txt | ||
- | new_certs_dir = \$dir | ||
- | certificate = \$dir/$tls_ca_CN.crt | ||
- | private_key = \$dir/$tls_ca_CN.key | ||
- | serial = \$dir/serial | ||
- | crl = \$dir/crl.pem | ||
- | RANDFILE = \$dir/.rand | ||
- | x509_extensions = usr_cert | ||
- | default_days = 3650 | ||
- | default_crl_days= 30 | ||
- | default_md = md5 | ||
- | preserve = no | ||
- | policy = policy_match | ||
- | |||
- | [ policy_match ] | ||
- | countryName = match | ||
- | stateOrProvinceName = match | ||
- | organizationName = match | ||
- | organizationalUnitName = optional | ||
- | commonName = supplied | ||
- | emailAddress = optional | ||
- | |||
- | [ policy_anything ] | ||
- | countryName = optional | ||
- | stateOrProvinceName = optional | ||
- | localityName = optional | ||
- | organizationName = optional | ||
- | organizationalUnitName = optional | ||
- | commonName = supplied | ||
- | emailAddress = optional | ||
- | |||
- | [ req ] | ||
- | default_bits = 2048 | ||
- | default_keyfile = privkey.pem | ||
- | distinguished_name = req_distinguished_name | ||
- | attributes = req_attributes | ||
- | x509_extensions = v3_ca | ||
- | string_mask = nombstr | ||
- | |||
- | [ req_distinguished_name ] | ||
- | countryName = Country Name (2 letter code) | ||
- | countryName_default = "$tls_country" | ||
- | countryName_min = 2 | ||
- | countryName_max = 2 | ||
- | stateOrProvinceName = State or Province Name (full name) | ||
- | stateOrProvinceName_default = "$tls_province" | ||
- | localityName = Locality Name (eg, city) | ||
- | localityName_default = "$tls_city" | ||
- | 0.organizationName = Organization Name (eg, company) | ||
- | 0.organizationName_default = "$tls_organization" | ||
- | organizationalUnitName = Organizational Unit Name (eg, section) | ||
- | commonName = Common Name (eg, your name or your server\'s hostname) | ||
- | commonName_max = 64 | ||
- | commonName_default = "$tls_ca_CN" | ||
- | emailAddress = Email Address | ||
- | emailAddress_default = "$tls_email" | ||
- | emailAddress_max = 40 | ||
- | |||
- | [ req_attributes ] | ||
- | challengePassword = A challenge password | ||
- | challengePassword_min = 4 | ||
- | challengePassword_max = 20 | ||
- | unstructuredName = An optional company name | ||
- | |||
- | [ usr_cert ] | ||
- | basicConstraints=CA:FALSE | ||
- | nsComment = "OpenSSL Generated Certificate" | ||
- | subjectKeyIdentifier=hash | ||
- | authorityKeyIdentifier=keyid,issuer:always | ||
- | |||
- | [ server ] | ||
- | basicConstraints=CA:FALSE | ||
- | nsCertType = server | ||
- | nsComment = "OpenSSL Generated Server Certificate" | ||
- | subjectKeyIdentifier=hash | ||
- | authorityKeyIdentifier=keyid,issuer:always | ||
- | |||
- | [ v3_req ] | ||
- | basicConstraints = CA:FALSE | ||
- | keyUsage = nonRepudiation, digitalSignature, keyEncipherment | ||
- | |||
- | [ v3_ca ] | ||
- | subjectKeyIdentifier=hash | ||
- | authorityKeyIdentifier=keyid:always,issuer:always | ||
- | basicConstraints = CA:true | ||
- | |||
- | [ crl_ext ] | ||
- | authorityKeyIdentifier=keyid:always,issuer:always | ||
- | HERE | ||
- | |||
- | # end of "generate_openssl_cnf.sh" | ||
- | </code> | ||
- | |||
- | Then run this code to generate the directory and openssl.cnf file: | ||
- | |||
- | <code> | ||
- | chmod +x generate_openssl_cnf.sh | ||
- | ./generate_openssl_cnf.sh | ||
- | </code> | ||
- | |||
- | ==== Generate CA cert/key ==== | ||
- | |||
- | <code> | ||
- | # note: we don't need '-newkey rsa:2048 ' because config-file.default_bits = 2048 | ||
- | |||
- | cd $tls_cert_dir/ ; | ||
- | /usr/bin/openssl req \ | ||
- | -days 3650 -nodes -new -x509 \ | ||
- | -keyout "$tls_ca_CN.key" \ | ||
- | -out "$tls_ca_CN.crt" \ | ||
- | -config $tls_cert_dir/openssl.cnf \ | ||
- | -batch \ | ||
- | -subj "/C=$tls_country/ST=$tls_province/L=$tls_city/O=$tls_organization/CN=$tls_ca_CN/emailAddress=$tls_email" \ | ||
- | ; | ||
- | /bin/chmod 0600 "$tls_ca_CN.key" ; | ||
- | </code> | ||
- | ==== Generate Server cert/key ==== | ||
- | |||
- | <code> | ||
- | cd $tls_cert_dir/ ; | ||
- | /usr/bin/openssl req -days 3650 -nodes -new \ | ||
- | -keyout $tls_server_CN.key \ | ||
- | -out $tls_server_CN.csr \ | ||
- | -extensions server \ | ||
- | -config $tls_cert_dir/openssl.cnf \ | ||
- | -batch \ | ||
- | -subj "/C=$tls_country/ST=$tls_province/L=$tls_city/O=$tls_organization/CN=$tls_server_CN/emailAddress=$tls_email" | ||
- | /usr/bin/openssl ca -days 3650 \ | ||
- | -out $tls_server_CN.crt \ | ||
- | -in $tls_server_CN.csr \ | ||
- | -extensions server \ | ||
- | -config $tls_cert_dir/openssl.cnf \ | ||
- | -batch | ||
- | /bin/chmod 0600 $tls_server_CN.key | ||
- | </code> | ||
- | |||
- | ==== Generate Client cert/key ==== | ||
- | |||
- | //NOTE: this code is the same as the Server above, except the paramter "extension server"// | ||
- | |||
- | <code> | ||
- | cd $tls_cert_dir/ ; | ||
- | /usr/bin/openssl req -days 3650 -nodes -new \ | ||
- | -keyout $tls_client_CN.key \ | ||
- | -out $tls_client_CN.csr \ | ||
- | -config $tls_cert_dir/openssl.cnf \ | ||
- | -batch \ | ||
- | -subj "/C=$tls_country/ST=$tls_province/L=$tls_city/O=$tls_organization/CN=$tls_client_CN/emailAddress=$tls_email" | ||
- | /usr/bin/openssl ca -days 3650 \ | ||
- | -out $tls_client_CN.crt \ | ||
- | -in $tls_client_CN.csr \ | ||
- | -config $tls_cert_dir/openssl.cnf \ | ||
- | -batch | ||
- | /bin/chmod 0600 $tls_client_CN.key | ||
- | </code> | ||
- | |||
- | ==== Check certificates ==== | ||
- | |||
- | <code> | ||
- | # View certificates: | ||
- | openssl x509 -text -noout -in $tls_ca_CN.crt | ||
- | openssl x509 -text -noout -in $tls_server_CN.crt | ||
- | openssl x509 -text -noout -in $tls_client_CN.crt | ||
- | # View CSRs (Certificate Signing Request): | ||
- | openssl req -text -noout -in $tls_server_CN.csr | ||
- | openssl req -text -noout -in $tls_client_CN.csr | ||
- | </code> | ||
- | |||
- | ==== Generate Diffie-Hellman key ==== | ||
- | |||
- | <code> | ||
- | openssl dhparam -out dh1024.$tls_projectname.pem 1024 | ||
- | </code> | ||
- | |||
- | ==== Generate TLS-Auth Key ==== | ||
- | |||
- | <code> | ||
- | openvpn --genkey --secret ta.$tls_projectname.key | ||
- | </code> | ||
- | |||
- | ==== Example of iptables ==== | ||
- | |||
- | This firewall example allows only ping and SSH between client-server and client-client. | ||
- | |||
- | Note that you should not use the 'client-to-client' option in the openvpn-server, because that would forward all packets with the openvpn-process and those packets will never see iptables and therefor make this firewall code useless. | ||
- | |||
- | <code> | ||
- | -A INPUT -i tun104 -s 10.4.0.0/24 -d 10.4.0.1 -p icmp -m icmp --icmp-type 8 -j ACCEPT | ||
- | -A INPUT -i tun104 -s 10.4.0.0/24 -d 10.4.0.1 -p tcp -m tcp --dport 2221 -j ACCEPT | ||
- | -A INPUT -i tun104 -j DROP | ||
- | -A FORWARD -i tun104 -o tun104 -s 10.4.0.0/24 -d 10.4.0.0/24 -p icmp -m icmp --icmp-type 8 -j ACCEPT | ||
- | -A FORWARD -i tun104 -o tun104 -s 10.4.0.0/24 -d 10.4.0.0/24 -p tcp -m tcp --dport 22 -j ACCEPT | ||
- | -A FORWARD -i tun104 -j DROP | ||
- | </code> | ||
- | |||
- | ===== Server TLS mode with client-auth ===== | ||
- | |||
- | This will be added later (contact me if you want help). | ||
- | |||
- | * This config will be similar to above "Server TLS-mode no-client-auth" but the a script is added that check username/password of clients. | ||
- | * when a client logs on, a login screen is presented where a username/password needs to be typed. | ||
- | |||
- | ==== server-tls-auth.conf ==== | ||
- | |||
- | |||
- | <code> | ||
- | # Add to above: server-tls.conf | ||
- | |||
- | auth-user-pass-verify /etc/openvpn/scripts/auth.pl via-file | ||
- | client-connect /etc/openvpn/scripts/connect.pl | ||
- | client-disconnect /etc/openvpn/scripts/disconnect.pl | ||
- | |||
- | # Required to .. | ||
- | username-as-common-name | ||
- | # Note: client-cert-not-required # DONT - we do require group-cert | ||
- | |||
- | </code> | ||
- | |||
- | |||
- | ==== client-tls-auth.conf ==== | ||
- | |||
- | |||
- | <code> | ||
- | # add to above client-tls.conf | ||
- | |||
- | auth-user-pass | ||
- | </code> | ||
- | |||