OpenVPN-Client unter FreeBSD

Sloop

Well-Known Member
Hi Leute,

ich hab zwei Fragen an die OpenVPN-Guru's unter euch:

1.) Kann ich durch den rc.conf Eintrag OpenVPN automatisch laden, und irgendwie einmalig mein Passwort für das Keyfile angeben, so dass es gespeichert wird? Ich hab kein Problem mir einfach ein neues Keyfile auf dem Server zu erstellen OHNE PASSWORT, aber mich interessiert das trotzdem. Angenommen ich hätte wirklich nur dieses eine einzige passwortgeschützte Zertifikat, wie könnte ich das bewerkstelligen? Ansonsten frägt mit FreeBSD bei jedem Systemstart, sobald der OpenVPN-Dienst gestartet wird, nach dem Passwort für das Zertifikat. Wenn ich da keine Eingabe mache, pausiert an dieser Stelle der Bootvorgang, und ein Loginprompt wird nie erscheinen.

2.) sobald der VPN-Tunnel zum Server steht, sollte ich doch normalerweise die DNS-Server des Servers übermittelt bekommen, und auch die Routen. Ich hab jedoch keinen DNS-Server erhalten. Das ist immer noch derselbe, und zwar der von meinem eigenen Internetrouter. Bei Windows und Linux Clients funktioniert das mit der selben Clientconfig auf Anhieb. Muss man bei BSD evtl. explizit irgendwas angeben? Ich möchte folgendes erreichen: wenn ich an meinem FreeBSD-Client bei aktiver VPN-Verbindung einen Hostnamen XYZ auflöse, dann soll sowohl auf meiner VPN_Gegenstelle gesucht werden, und falls nicths gefunden, dann lokal auf meinem ISP-Router.

Danke schonmal im Voraus.
 
zu 1.: ja das geht. Beim Bauen von OpenVPN kannst du angeben, dass du das Passwort in eine Datei schreiben willst. Wie du das in die rc.conf einträgst, siehst du in /usr/local/etc/rc.d/openvpn

zu 2. Ohne entsprechende Konfigurationsdateien wird das vermutlich nur gestocher.

HTH
 
zu 1.) danke, schau ich mir genau an.

zu 2.)

Server:
Code:
daemon openvpnserver
writepid /var/run/openvpn.pid
dev tun
tun-mtu 1400
proto udp
port 1194
script-security 3 system
ifconfig-pool-persist /var/ipfire/ovpn/ovpn-leases.db 3600
tls-server
ca /var/ipfire/ovpn/ca/cacert.pem
cert /var/ipfire/ovpn/certs/servercert.pem
key /var/ipfire/ovpn/certs/serverkey.pem
dh /var/ipfire/ovpn/ca/dh1024.pem
server 10.58.20.0 255.255.255.0
keepalive 10 60
status-version 1
status /var/log/ovpnserver.log 30
cipher BF-CBC
;folgendes habe ich nicht stehen, denn ich moechte nicht,dass die Clients über das default Gateway des Servers im Internet surfen. Sonst würden sie das default gateway vom Server erhalten
;push "redirect-gateway def1"
push "dhcp-option DOMAIN beispiel.de"
push "dhcp-option DNS 192.168.1.1"
push "dhcp-option WINS 192.168.1.1"
push "route 192.168.1.0 255.255.255.0"
max-clients 30
tls-verify /var/ipfire/ovpn/verify
crl-verify /var/ipfire/ovpn/crls/cacrl.pem
user nobody
group nobody
persist-key
persist-tun
verb 3

Client (FreeBSD):
Code:
tls-client
client
dev tun
proto udp
auth-nocache
tun-mtu 1400
remote 1.2.3.4 1194
pkcs12 mein-cert.p12
cipher BF-CBC
verb 3
ns-cert-type server
tls-remote 1.2.3.4

Wie gesagt, normalerweise funzt es bei Linux- und Windowsclients. Da wird dann nach der VPN-Konnektierung auch das DNS-Suffix mit aufgenommen. Hab auch in meine client-config die Zeile "allow-pull-fqdn" mal probiert, brachte aber auch keinen Erfolg. Müsste ich evtl. die nsswitch.conf extra anpassen im FreeBSD, oder wie? Die sieht aber meines Erachtern korrekt aus.
 
Zuletzt bearbeitet:
Zusatzfragen:

Auf der Serverseite nutzt du 192.168.1.x
Was nutzt du auf der Clientseite?
Sehe ich das richtig und du hast die Konfiguration aus irgend einem "Howto" kopiert? "daemon openvpnserver" kenne ich zB gar nicht.
 
push "dhcp-option DNS 192.168.1.1"
macht für mich erstmal wenig Sinn. Dein "VPN-Device" bekommt eine IP aus dem 10.58.20.x-Netz. Die Netzwerkkarte im Client-Netz hat bereits eine IP. Du "pushst" eine Route, das passt. Aber für welchen DHCP-Client willst du den DNS setzen? Wohl nur für das VPN-Device, oder? Kommen die DNS-Anfragen denn von diesem Device? Vermutlich nicht.
 
Columbo: Mein OpenVPN-Server läuft auf der IPFire. Ich sehe das Problem viel weniger in der VPN-Configuration an sich, sondern viel eher am System. Wie ich schon sagte, auf Linux und Windows-Clients funzt es einwandfrei. Ich denke ich muss meinem FreeBSD irgendwie beibringen, dass er seine resolv.conf anpasst nach einer erfolgreichen TUN-Verbindung. Ich habe dazu gegoggelt und im Arch-Linux Forum HIER wird das genau beschrieben.. Jedoch ist das Skript für die Bash gedacht und funzt nicht mit meiner tcsh.

Hat da jemand etwas (t)csh-konformes in dieser Richtung? Ich denke das muss es sein. Openresolv Paket ist schon installiert und den Symlink habe ich auch angefertigt. Fehlt nur noch das passende Skript, lauffähig unter BSD.
 
Zumindest ich kann dir nur versuchen zu helfen, wenn ich den Aufbau verstehe. Wenn das andere auch so können, ist das schön. Mir reichen die Infos jedenfalls nicht und deswegen bin ich raus.
 
Columbo, ich verstehe deinen Frust nicht. Es geht um die resolv.conf lokal auf der FreeBSD Box. In dieser Wiki auf diesem Forum konnte ich den Hinweis finden, dass BSD keine Veränderungen am DNS durchführt. Das bestätigt das von mir festgestellte Verhalten. Das dort gezeigte simple Skript habe ich auch gesehen, wird jedoch meinen Ansprüchen nicht gerecht. Eine saubere Lösung wäre mir wirklich wie von openresolv demonstriert (siehe Link vom Arch-Linux-Forum). Ich müsste nur das Skript lauffähig bekommen.
 
@Sloop
Warum installierst du dir nicht "bash", wenn du meinst, dass das dein Problem löst?

Columbo geht es wohl eher darum, dass du nicht einfach eine Config kopierst und nicht weisst, was genau du da machst!
 
Columbo, ich verstehe deinen Frust nicht. Es geht um die resolv.conf lokal auf der FreeBSD Box.

Kein Frust, sorry wenn das so rüberkam. Ich wollte lediglich sagen: Ich kann dir ohne weitere Infos nicht helfen und dir damit begründen, warum ich mich "nicht mehr melde". :)

Den Hinweis, dass der DNS nicht per Config zugewiesen werden kann, findest du übrigens auch in der offiziellen Dokumentation :) Dort steht auch, dass du es mit einem Script lösen kannst.

Gruß

Lord_x: Grob passt das. Wobei das zu sehr nach "RTFM" klingt, was ich nicht sagen wollte.
 
@Lord_x: bash ist schon installiert. Und zur config, siehe unten. Ich bin kein kleines Baby, das sich Skripte kopiert, chmod +x drüberjagt und ausführt! Ich verstehe nicht, wie du/ihr auf solche Selbstinterpretationen kommt? Wenn ihr an der VPN-config irgendwas auszusetzen habt, so bin ich ganz Ohr und dankbar, doch solche Antworten zeugen nicht wirklich von überzeugender Hilfestellung. Sorry, just my 2 cents. Zu den Configs möchte ich hinzufügen:

- Der OpenVPN Server läuft auf einer IPFire. Dort kann ich mir über die Weboberfläche das fertige Clientpaket runterladen, auf den Client transferieren und einsetzen. Dieses Paket besteht aus zwei Dateien, der fertigen client-config und dem passwortgeschützten Zertifikat. Die Konfiguration auf dem Server ist nicht von mir, kann sie aber bei Bedarf einsehen.

Wenn ich mir nun diese zwei Dateien auf zig Linux- oder Windows-Client verwende (mit dem OpenVPN-Client 2.2.2) dann funktioniert das bisher immer auf Anhieb. Wenn sich der Client am Server verbindet, kriegt er automatisch die Routen, die DNS-Server des VPN-Knotens, und auch die Suffix-Suchlisten.

Nun installiere ich das erstmalig auf der FreeBSD Box und stelle fest, dass diese AUTOMATISCHE Anpassung der resolv.conf, oder welcher Datei auch immer, NICHT stattfindet. Aus einer ganz einfachen Schlussfolgerung, kann ich doch an diesem Punkt schon mit 99%iger Sicherheit sagen, dass es wohl etwas mit der FreeBSD Box zu tun haben muss. Ich denke das ist euch doch auch klar, wenn nicht bitte korrigiert mich.

Durch meine Recherchen habe ich auf der Wiki-Seite hier im BSD-Forum gesehen, dass FreeBSD anscheinend tatsächlich diese Anpassung verhindert, verbietet oder wie auch immer. Ich hatte vom Paket openresolv gelesen, wie es in ArchLinux gezeit wurde, jedoch wüßte ich zu gerne ob ich das wirklich brauche oder nicht. Das Paket openresolv gibt es laut pkgng, und wenn man es installiert, dann legt es seine Files unter /usr/local/sbin/resolconf ab. Wobei es auch wahrscheinlich eine BSD-fixe Version dieses Tools gibt, die liegt defaultmäßig unter /sbin/resolvonf. Worin liegen den die grundelegenden Unterschiede, welche executable benötige ich denn eigentlich?

Und meine immer ncoh aktuelle Frage lautet: benötige ich überhaupt ein Skript, dass diese Anpassung durchführt, oder kann ich mittels OpenVPN und bordeigenen BSD-Mitteln dieses Ziel erreichen?

Danke und Grüße,
Sloop.
 
@Lord_x: bash ist schon installiert. ... Ich bin kein kleines Baby, das sich Skripte kopiert, chmod +x drüberjagt und ausführt! Ich verstehe nicht, wie du/ihr auf solche Selbstinterpretationen kommt?
Wir/Ich können nur das lesen, was du schreibst und von der "bash", dass diese installiert sein soll, hast du bisher nichts geschrieben. Nur folgendes:
Sloop schrieb:
Ich müsste nur das Skript lauffähig bekommen
Darauf dann meine Antwort mit der "Bash-Installation".

Zweitens könntest du die Routen ect. doch einfach mal manuell anlegen und dann schauen was passiert...
Code:
route add default x.x.x.x
 
die default route soll gerade nicht geändert werden :)

ich seh mir das heute abend mal an, weil ich vom Grundsatz her irgendwann einmal auch den DNS bekannt machen wollte. Das dies problematisch ist, war mir bislang nicht bekannt.

Gruß
 
Hi nochmal,

sorry wenn ich dich wieder unterbreche, aber mit der Route hab ich kein Problem :) es geht mir um die DNS-Auflösung. Ich bin jetzt soweit angelangt, dass ich das Script von dem genannten Link übernommen habe und es ausgeführt wird. Das Problem lag letztendlich an 3 Fehlerteufeln:

1.) ich musste das Shebang anpassen, den bash liegt bei mir natürlich nicht auf /bin :)
2.) Das Skript wie es im Archlinux-Forum gepostet wurde, war falsch. Da landeten die Anführungszeichen auf einer extra Zeile, und da die Zeile mit einem " nur angegeben war, konnte bash diesen Befehl nicht finden. Bäääh
3.) ich musste noch den Pfad zur resolvconf anpassen, die liegt bei mir auf /sbin/resolvconf

Ich habe aber noch diesen Haken:

sobald ich meine VPN-Verbindung hergestellt habe, wird meine /etc/resolv.conf angepasst für mein tun0 interface. Das Problem ist: das Skript oder der resolvconf schreibt mir keine Linefeeds zwischen den Einträgen rein. Das Skript sieht so aus, zur Verdeutlichung:

Code:
#!/usr/local/bin/bash
# Parses DHCP options from openvpn to update resolv.conf
# To use set as 'up' and 'down' script in your openvpn *.conf:
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf
#
# Used snippets of resolvconf script by Thomas Hood <jdthood@yahoo.co.uk>
# and Chris Hanson
# Licensed under the GNU GPL.  See /usr/share/common-licenses/GPL.
#
# 05/2006 chlauber@bnc.ch
#
# Example envs set from openvpn:
# foreign_option_1='dhcp-option DNS 193.43.27.132'
# foreign_option_2='dhcp-option DNS 193.43.27.133'
# foreign_option_3='dhcp-option DOMAIN be.bnc.ch'

[ -x /sbin/resolvconf ] || exit 0

case $script_type in

up)
   for optionname in ${!foreign_option_*} ; do
      option="${!optionname}"
      echo $option
      part1=$(echo "$option" | cut -d " " -f 1)
      if [ "$part1" == "dhcp-option" ] ; then
         part2=$(echo "$option" | cut -d " " -f 2)
         part3=$(echo "$option" | cut -d " " -f 3)
         if [ "$part2" == "DNS" ] ; then
            IF_DNS_NAMESERVERS="$IF_DNS_NAMESERVERS $part3"
         fi
         if [ "$part2" == "DOMAIN" ] ; then
            IF_DNS_SEARCH="$part3"
         fi
      fi
   done
   R=""
   if [ "$IF_DNS_SEARCH" ] ; then
           R="${R}search $IF_DNS_SEARCH"
   fi
   for NS in $IF_DNS_NAMESERVERS ; do
           R="${R}nameserver $NS"
   done
   echo -n "$R" | /sbin/resolvconf -a "${dev}.inet"
   ;;
down)
   /sbin/resolvconf -d "${dev}.inet"
   ;;
esac

Ich dachte es läge an dem echo -n, also hab ich das -n weggemacht hinter dem echo Befehl, aber das brachte keine Abhilfe.

Außerdem würde ich trotzdem noch gerne wissen, OB ich überhaupt openresolv benötige oder nicht.

Grüße,
Sloop.
 
Hmm... mit printf hab ichs auch nicht hingekriegt. Er schreibt ja alle ermittelten Werte hintereinander auf. Er reiht quasi all die Parameter in eine einzige Zeile auf, und schreibt das immer als Menge in die Variable. So hab ich das zumindest als Laie interpretiert. Mal ganz unabhängig vom Skript:

wie macht es denn der Rest der BSD-ler, die VPN einsetzen und solche dynamischen connection managen will? Eigentlich ist ja für sowas das Paket resolvconf zuständig, oder nicht? Ich habe mir jetzt die man-page von resolvconf, resolv.conf und der resolvconf.conf durchgelesen. Was mich sehr verwirrt ist die Aussage, dass resolvconf eigentlich ein Projekt von Openresolv ist. Wieso gibts dann aber ein extra Openresolv Paket in FreeBSD, das man nachträglich installieren kann? Ob ich openresolv installiert habe oder nicht, resolvconf gibts immer unter /sbin/resolvconf

Und wie müsste man resolvconf denn anpassen, damit das mit einer dynamischen VPN-Verbindung so zusammenarbeitet? Bin für jede Hilfestellung dankbar.

Grüße
Sloop
 
Also ich komm da echt nicht weiter, und würde mich echt freuen, wenn mir ein Pro unter euch, unter die Arme greifen könnte. Ich hab schon sämtliche manuals durchgelesen und nach meinem Verständnis brauche ich das in FreeBSD erhältliche Paket "openresolv" gar nicht. Denn OpenVPN stellt dieses Skript zur Verfügung. Das ist zwar bei meiner FreeBSD-Installation nicht dabei gewesen in dem OpenVPN-Paket, da es aber in bash geschrieben ist kann man es problemlos übernehmen. Dieses Skript sammelt die Optionen nachdem die VPN-Verbindung initiiert wurde, und übergibt sie dann an den resolvconf, der wiederum aktualisiert daraufhin die /etc/resolv.conf. Dabei wird der FreeBSD-interne Prozess unter /sbin/resolvconf bemüht (which resolvconf). Das ganze funktioniert soweit, mit dem einzigsten Problem:

Das OpenVPN-Skript trägt die Änderungen in meine /etc/resolv.conf mit falschen Linefeeds ein. Hier als Beispiel:

meine originale /etc/resolv.conf, bevor ich mit VPN verbunden bin:
Ich hab hier zu Hause eine Fritzbox, mit der ich ins Internet gelange, und diese hat die IP 192.168.0.1
Code:
# Generated by resolvconf
search fritz.box
nameserver 192.168.0.1

Sobald ich meine VPN-Verbindung hergestellt habe, sieht die /etc/resolv.conf so aus:
Code:
# Generated by resolvconf
search myvpndomain.denameserver 172.16.0.1nameserver 172.16.0.2 fritz.box
nameserver 192.168.0.1

Man sieht hier, dass die Leerzeichen und die Linefeeds gar nicht übereinstimmen. Eigentlich sollte es doch richtigerweise so ausschauen:
# Generated by resolvconf
search myvpndomain.de fritz.box
nameserver 172.16.0.1
nameserver 172.16.0.2
nameserver 192.168.0.1

Das Skript habe ich ja weiter vorne gepostet. Zur besseren Verdeutlichung hier nochmal das Skript:
Code:
#!/usr/local/bin/bash                                                                                                                
#                                                                                                                          
# Parses DHCP options from openvpn to update resolv.conf                                                                   
# To use set as 'up' and 'down' script in your openvpn *.conf:                                                             
# up /etc/openvpn/update-resolv-conf                                                                                       
# down /etc/openvpn/update-resolv-conf                                                                                     
#                                                                                                                          
# Used snippets of resolvconf script by Thomas Hood <jdthood@yahoo.co.uk>                                                  
# and Chris Hanson                                                                                                         
# Licensed under the GNU GPL.  See /usr/share/common-licenses/GPL.                                                         
#                                                                                                                          
# 05/2006 chlauber@bnc.ch                                                                                                  
#                                                                                                                          
# Example envs set from openvpn:                                                                                           
# foreign_option_1='dhcp-option DNS 193.43.27.132'                                                                         
# foreign_option_2='dhcp-option DNS 193.43.27.133'                                                                         
# foreign_option_3='dhcp-option DOMAIN be.bnc.ch'                                                                                                                                                                                             
[ -x /sbin/resolvconf ] || exit 0                                                                                                                                                                                                                     
case $script_type in                                                                                                       
up)
for optionname in ${!foreign_option_*} ; do
option="${!optionname}"
echo $option
part1=$(echo "$option" | cut -d " " -f 1)
if [ "$part1" == "dhcp-option" ] ; then
part2=$(echo "$option" | cut -d " " -f 2)
part3=$(echo "$option" | cut -d " " -f 3)
if [ "$part2" == "DNS" ] ; then
IF_DNS_NAMESERVERS="$IF_DNS_NAMESERVERS $part3"
fi
if [ "$part2" == "DOMAIN" ] ; then
IF_DNS_SEARCH="$part3"
fi
fi
done
R=""
if [ "$IF_DNS_SEARCH" ] ; then
R="${R}search $IF_DNS_SEARCH"
fi
for NS in $IF_DNS_NAMESERVERS ; do
R="${R}nameserver $NS"
done
echo -n "$R" | /sbin/resolvconf -a "${dev}.inet"
;;
down)
/sbin/resolvconf -d "${dev}.inet"
;;
esac

Bin für jeden Tip dankbar.
 
Zuletzt bearbeitet:
Wooohaaa! Ich glaub ich hab's :-) hab mich an dem Script von /sbin/dhclient-script orientiert und mir folgendes gebastelt:

Code:
#!/usr/local/bin/bash
[ -x /sbin/resolvconf ] || exit 0
case $script_type in

        up)

        tmpres=/var/run/resolv.conf.${dev}.inet
        rm -f $tmpres

                for optionname in ${!foreign_option_*} ; do
                        option="${!optionname}"
                        echo $option
                        part1=$(echo "$option" | cut -d " " -f 1)
                        if [ "$part1" == "dhcp-option" ] ; then
                                part2=$(echo "$option" | cut -d " " -f 2)
                                part3=$(echo "$option" | cut -d " " -f 3)
                                if [ "$part2" == "DNS" ] ; then
                                        IF_DNS_NAMESERVERS="$IF_DNS_NAMESERVERS $part3"
                                fi
                                if [ "$part2" == "DOMAIN" ] ; then
                                        IF_DNS_SEARCH="$part3"
                                fi
                        fi
                done
                #R=""
                if [ "$IF_DNS_SEARCH" ] ; then
                #       R="${R}search $IF_DNS_SEARCH"
                echo "search $IF_DNS_SEARCH" >>$tmpres
                fi
                for NS in $IF_DNS_NAMESERVERS ; do
                #       R="${R}nameserver $NS"
                echo "nameserver $NS" >>$tmpres
                done
                #echo -n "$R" | /sbin/resolvconf -a "${dev}.inet"
                if [ -f $tmpres ]; then
                if [ -f /etc/resolv.conf.tail ]; then
                        cat /etc/resolv.conf.tail >>$tmpres
                fi

                case $resolvconf_enable in
                # "no", "false", "off", or "0"
                [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0)
                        # When resolv.conf is not changed actually, we don't
                        # need to update it.
                        # If /usr is not mounted yet, we cannot use cmp, then
                        # the following test fails.  In such case, we simply
                        # ignore an error and do update resolv.conf.
                        if cmp -s $tmpres /etc/resolv.conf; then
                                rm -f $tmpres
                                #return 0
                        fi 2>/dev/null

                        # In case (e.g. during OpenBSD installs)
                        # /etc/resolv.conf is a symbolic link, take
                        # care to preserve the link and write the new
                        # data in the correct location.

                        if [ -f /etc/resolv.conf ]; then
                                cat /etc/resolv.conf > /etc/resolv.conf.save
                        fi
                        cat $tmpres > /etc/resolv.conf

                        # Try to ensure correct ownership and permissions.
                        chown -RL root:wheel /etc/resolv.conf
                        chmod -RL 644 /etc/resolv.conf
                        ;;

                *)
                        /sbin/resolvconf -a ${dev}.inet < $tmpres
                        ;;
                esac

                rm -f $tmpres

                #return 0
        fi

        #return 1

                ;;
        down)
                /sbin/resolvconf -d "${dev}.inet"
                ;;
esac

somit wird nicht eine einzige Zeile an den resolvconf übergeben, sondern ich schreib erstmal alles in deine temporäre resolv.conf. Die richtige Mischung übernimmt dann der resolvconf. Funktioniert 1a *FREU*

Falls es also sonst noch jemanden mit diesem Problem gibt, einfach mal probieren obs klappt und feedback geben.

Danke trotzdem an allen, und viele Grüße,
Sloop.
 
Wenn du jetzt noch solch seltsamen Konstrukte wie
Code:
                for optionname in ${!foreign_option_*} ; do
                        option="${!optionname}"

umschreibst, kannst du dir die ganze Bash sparen.
 
Wenn du mir erklärst, wie, gerne. Und was ist daran so schlimm, wenn ich die bash verwendet, statt einfach die shell zu nehmen?
 
Nö, ich habe keine Ahnung, was das macht, ich guck mir gar nicht erst an, was die Bash so alles nonkonformes macht. :)

Die Bash sollte nach Möglichkeit in Shellskripten vermieden werden, weil man nicht annehmen kann, dass sie auf allen System vorhanden ist. Klar, für deinen Fall reicht das, weil es dein Privates Skript ist, aber mMn sollte man sich so etwas nicht angewöhnen.
 
Verstehe was du meinst, und geb dir da recht. Da ich aber nicht so der Guru bin in Shellprogrammierung und wie bereits erläuter für meinen privaten einmaligen Einsatzgebrauch notwendig war, denke ich dass ich es erstmal so belasse.

Danke für den Hinweis.
 
Zurück
Oben