Temat: Openvpn - dwu stopniowa walidacja

Witam Kolegów

Mam uruchomiony serwer openvpn na backfire 10.03.1
Wszystko działa w porządku ( uwierzytelnianie oparte na certyfikacie)
Chciałbym teraz dodać jeszcze dodatkową walidację opartą o login i hasło. I nie wiem jak to ugryźć.
Oto moje konfigi:

/etc/config/openvpn

config 'openvpn' 'Serwer_tun'
        option 'enable' '1'
        option 'port' '1194'
        option 'proto' 'udp'
        option 'dev' 'tun'
        option 'client_to_client' '1'
        option 'keepalive' '10 120'
        option 'comp_lzo' '1'
        option 'persist_key' '1'
        option 'persist_tun' '1'
        option 'verb' '3'
        option 'mute' '20'
        option 'ifconfig_pool_persist' '/tmp/ipp.txt'
        option 'status' '/tmp/openvpn-status.log'
     option 'ca' '/etc/openvpn/Centrum_Serwerow_chain.crt'
     option 'cert' '/etc/openvpn/openvpn.crt'
     option 'key' '/etc/openvpn/openvpn.pem'
     option 'dh' '/etc/openvpn/dh1024.pem'
        option 'server' '172.16.10.0 255.255.255.0'  #this should be on a completely different subnet than your LAN
        list 'push' 'route 192.168.22.0 255.255.255.0' #this should MATCH your current LAN info
        list 'push' 'dhcp-option DNS 192.168.22.1' #this should MATCH your current LAN info
        list 'push' 'dhcp-option DOMAIN 192.168.22.1' #this should MATCH your current LAN info
#     option 'explicit-exit-notify' '2'
     list 'push' 'explicit-exit-notify 3'


Klient:

client
proto udp
dev tun

remote vpn.domena.pl 1194
ca Centrum_Klientow_chain.crt 
pkcs12 klient1.p12
ns-cert-type server
comp-lzo
persist-key
persist-tun
nobind
resolv-retry infinite
verb 3
mute 10

Z góry dziękuje za wszelkie sugestie

2

Odp: Openvpn - dwu stopniowa walidacja

Coś w ten deseń: http://rpc.one.pl/index.php/lista-artyk … ptem-hasem

Masz niepotrzebny router, uszkodzony czy nie - chętnie przygarnę go.

3 (edytowany przez advcron 2013-03-28 09:11:19)

Odp: Openvpn - dwu stopniowa walidacja

Dokładnie o to mi chodzi Cezary. Według tego opisu ( Jeden z lepszych w necie) zrobiłem to swego czasu na Debianie i wszystko działa jak należy. Nie wiem natomiast jak to przenieść to na openwrt. Wydaje mi się że brakuje pluginów w paczce ipk  np:
plugin /usr/lib/openvpn/openvpn-auth-pam.so

( luci podpowiada  /usr/bin/ovpn-userpass via-env) tylko nie ma tam takiego pliku.

Dodatkowo nie wiem czy wszystkie użyte opcję w tym opisie da są wkompilowane w paczkę opevpn.ipk

4 (edytowany przez rpc 2013-03-28 13:05:39)

Odp: Openvpn - dwu stopniowa walidacja

script-security 3
username-as-common-name
auth-user-pass-verify /etc/openvpn/ver-pass.sh via-env

plik ver-pass.sh o zawartości

#!/bin/sh
pass=`awk "\\\$1 == \"${username}\" { print substr(\\\$0,length(\\\$1)+2) }" /etc/openvpn/openvpn-auth`
test -n "$pass" && test "$pass" == "${password}" && exit 0
exit 1

plik openvpn-auth o zawartości

user1 pass1
user2 pass2

nie zapomnij o
chmod 755 /tmp/ver-pass.sh

na kliencie w pliku konfiguracyjnym dodaj

auth-user-pass

A jak mają być zamiast haseł hashe to można i tak

#!/bin/sh
pass=`awk "\\\$1 == \"${username}\" { print substr(\\\$0,length(\\\$1)+2) }" /etc/openvpn/openvpn-auth`
test -n "$pass" && test "$pass" == "`printf ${password} | md5sum | awk '{print $1}'`" && exit 0
exit 1

plik openvpn-auth wyglądałby wtedy

user1 hashedpass1
user2 hashedpass2
user3 hashedpass3
user4 hashedpass4

jak widać jest hash md5sum hasła


Źródło i przykłady z:
http://www.linksysinfo.org/index.php?th … ion.32559/

5

Odp: Openvpn - dwu stopniowa walidacja

https://github.com/troydm/ovpnauth.sh

6 (edytowany przez advcron 2013-03-29 08:55:03)

Odp: Openvpn - dwu stopniowa walidacja

Dziękuję koledzy wszystko działa. smile

Teraz chciałbym iść za ciosem i wprowadzić walidację common name z certyfikatu = username
Dodałem więc opcję

tls-verify "/etc/openvpn/client/vpncheckCN-cert.sh /etc/openvpn/client/userlist.txt"

userlist.txt

Jan_Nowak jnowak

vpncheckCN-cert.sh - z artykułu na stronie rpc

#!/bin/sh
#    vpncheckCN-cert -- an OpenVPN tls-verify script
#    """""""""""""""""""""""""""""""""""""""""""
#
#    This script checks if the peer is in the allowed
#    user list by checking the CN (common name) of the
#    X509 certificate against a provided text file.
#
#    For example in OpenVPN, you could use the directive
#    (as one line):
#
#    tls-verify "/etc/openvpn/vpncheckCN-cert.sh
#                /etc/openvpn/userlist.txt"
#
#    This would cause the connection to be dropped unless
#    the client common name is within the userlist.txt.
#
#    Special care has been taken to ensure that this script
#    also works on openwrt systems where only busybox is
#    available
#
#    Written by Robert Penz <robert[at]penz.name> under the GPL 2
#    Parts are copied from the verify-cn sample OpenVPN
#    tls-verify script.
#
#    Modifications made by Rafal Cichosz (rpc[at]rpc.one.pl)


[ $# -eq 3 ] || { echo usage: vpncheckCN-cert.sh userfile certificate_depth X509_NAME_oneline ; exit 255 ; }

# $2 -> certificate_depth
if [ $2 -eq 0 ] ; then
# $3 -> X509_NAME_oneline
# $1 -> cn we are looking for
grep -q -w "^`expr match "$3" ".*/CN=\([^/][^/]*\)"`" "$1" && exit 0
exit 1
fi
exit 0
 

Po tym zabiegu otrzymuję error w logach :

 root@router:/etc/openvpn/client# tail -f /root/logs/system.log
Mar 28 22:52:03 openvpn(Serwer)[16919]: 76.72.74.72:2387 Re-using SSL/TLS context
Mar 28 22:52:03 openvpn(Serwer)[16919]: 76.72.74.72:2387 LZO compression initialized
Mar 28 22:52:03 openvpn(Serwer)[16919]: 76.72.74.72:2387 Control Channel MTU parms [ L:1542 D:138 EF:38 EB:0 ET:0 EL:0 ]
Mar 28 22:52:03 openvpn(Serwer)[16919]: 76.72.74.72:2387 Data Channel MTU parms [ L:1542 D:1450 EF:42 EB:135 ET:0 EL:0 AF:3/1 ]
Mar 28 22:52:03 openvpn(Serwer)[16919]: 76.72.74.72:2387 TLS: Initial packet from 76.72.74.72:2387, sid=0e3c03b5 a44eb34d
Mar 28 22:52:08 openvpn(Serwer)[16919]: 76.72.74.72:2387 VERIFY SCRIPT OK: depth=2, /C=PL/O=Certification_Authority/OU=Administracja/CN=Centrum_Certyfikacji_ROOT_CA/OU=Trust_Network
Mar 28 22:52:08 openvpn(Serwer)[16919]: 76.72.74.72:2387 VERIFY OK: depth=2, /C=PL/O=Certification_Authority/OU=Administracja/CN=Centrum_Certyfikacji_ROOT_CA/OU=Trust_Network
Mar 28 22:52:08 openvpn(Serwer)[16919]: 76.72.74.72:2387 VERIFY SCRIPT OK: depth=1, /C=PL/O=Certification_Authority/OU=Administracja/CN=Centrum_Klientow/OU=Trust_Network
Mar 28 22:52:08 openvpn(Serwer)[16919]: 76.72.74.72:2387 VERIFY OK: depth=1, /C=PL/O=Certification_Authority/OU=Administracja/CN=Centrum_Klientow/OU=Trust_Network
Mar 28 22:52:08 openvpn(Serwer)[16919]: 76.72.74.72:2387 VERIFY SCRIPT ERROR: depth=0, /C=PL/ST=Ma_xC5_x82opolska/L=M_xC3_xB3w/O=INTRANET__SC_/OU=Administracja/CN=Jan_Nowak/emailAddress=pk@domena.pl/businessCategory=Private_SSL/
Mar 28 22:52:08 openvpn(Serwer)[16919]: 76.72.74.72:2387 TLS_ERROR: BIO read tls_read_plaintext error: error:140890B2:lib(20):func(137):reason(178)
Mar 28 22:52:08 openvpn(Serwer)[16919]: 76.72.74.72:2387 TLS Error: TLS object -> incoming plaintext read error
Mar 28 22:52:08 openvpn(Serwer)[16919]: 76.72.74.72:2387 TLS Error: TLS handshake failed
Mar 28 22:52:08 openvpn(Serwer)[16919]: 76.72.74.72:2387 SIGUSR1[soft,tls-error] received, client-instance restarting

Czyli jak dobrze rozumiem VERIFY SCRIPT ERROR: depth=0 tyczy się już certyfikatu klienta co wskazywało by na błąd w skrypcie, bądź nie trafia on ze sprawdzeniem do pliku userlist.txt

O c tu chodzi?


Żeby nie pisać nowego postu:

Jeśli plik userlist wygląda tak:

Jan_Kowalski

a skrypt check_cn - oryginalny bez zmian dokdananych przez rpc

[ $# -eq 3 ] || { echo usage: ovpnCNcheck.sh userfile certificate_depth X509_NAME_oneline ; exit 255 ; }

# $2 -> certificate_depth
if [ $2 -eq 0 ] ; then
    # $3 -> X509_NAME_oneline
    # $1 -> cn we are looking for
    grep -q "^`expr match "$3" ".*/CN=\([^/][^/]*\)"`$" "$1" && exit 0
    exit 1
fi

exit 0

To się łączy ( Sprawdza jedynie czy dany cn z certyfikatu jest na liście ). Problem w tym że nie sprawdza cn=uername

7 (edytowany przez advcron 2013-03-30 11:05:58)

Odp: Openvpn - dwu stopniowa walidacja

Użytkownik kiniu poprosił o konfigi oto one:
Zainstalowany Pakiet: openvpn


/etc/config/openvpn

config 'openvpn' 'Serwer'
    option 'config' '/etc/openvpn/openvpn_2step.conf'
    option 'enable' '1'

/etc/openvpn/openvpn_2step.conf

port 1194
proto udp
dev tun
client-to-client
keepalive 10 120
comp-lzo
persist-key
persist-tun 
verb 3
mute 20
ifconfig-pool-persist /tmp/ipp.txt
status /tmp/openvpn-status.log
ca /etc/openvpn/ssl/Centrum_Serwerow_chain.crt
cert /etc/openvpn/ssl/openvpn.crt
key /etc/openvpn/ssl/openvpn.pem
crl-verify /etc/openvpn/ssl/klient.crl
dh /etc/openvpn/ssl/dh1024.pem
script-security 3
username-as-common-name
auth-user-pass-verify /etc/openvpn/client/ver-pass-hash.sh via-env
tls-verify "/etc/openvpn/client/vpncheckCN-cert.sh /etc/openvpn/client/userlist.txt"
server 172.16.30.0 255.255.255.0  #this should be on a completely different subnet than your LAN
push route 192.168.55.0 255.255.255.0 #this should MATCH your current LAN info
push dhcp-option DNS 192.168.55.1 #this should MATCH your current LAN info
push dhcp-option DOMAIN 192.168.55.1 #this should MATCH your current LAN info
push explicit-exit-notify 3

/etc/openvpn/client/openvpn-auth-hash

user1 ee1ef59634696d407dbf20e9cde974ee
user2 d1ef596444696d407dbf20e9cde974da

/etc/openvpn/client/ver-pass-hash.sh

#!/bin/sh
pass=`awk "\\\$1 == \"${username}\" { print substr(\\\$0,length(\\\$1)+2) }" /etc/openvpn/client/openvpn-auth-hash`
echo $pass >> /etc/openvpn/client/1
test -n "$pass" && test "$pass" == "`printf ${password} | md5sum | awk '{print $1}'`" && exit 0
exit 1

/etc/openvpn/client/vpncheckCN-cert.sh

#!/bin/sh


[ $# -eq 3 ] || { echo usage: ovpnCNcheck.sh userfile certificate_depth X509_NAME_oneline ; exit 255 ; }

# $2 -> certificate_depth
if [ $2 -eq 0 ] ; then
    # $3 -> X509_NAME_oneline
    # $1 -> cn we are looking for
    grep -q "^`expr match "$3" ".*/CN=\([^/][^/]*\)"`$" "$1" && exit 0
    exit 1
fi
exit 0

/etc/openvpn/client/userlist.txt

Jan_Nowak
Anna_Kowalska



Klient OPENVPN - Stacja Windows

tunel.ovpn

client
proto udp
dev tun
remote 77.77.77.77 1194
ca Centrum_Klientow_chain.crt 
auth-user-pass
pkcs12 klient1.p12
ns-cert-type server
comp-lzo
persist-key
persist-tun
nobind
resolv-retry infinite
verb 3
mute 10

Czy można tak zrobić przez GUI Cezarego ? To nie wiem bo używam luci.
W luci natomiast nie mam wszystkich użytych opcji. Ja robiłem to przez ssh.


Cały czas pozostaje problem username=cn.
Z tego co mi się wydaje to należałoby dodać jakąs dodatkową walidację w pliku ver-pass-hash.sh. Po sprawdzeniu zgodności hasła. Tylko nie wiem za bardzo jak.
Ponadto wydaje mi się iż problem w przerobionych skryptach przez rpc wynika z użytej opcji "-w" w grep. W --help w openwrt nie ma jej i przez to gdy do pliku userlist.txt dodamy kolumnę z username np: Jan_Nowak jnowak,
to waliadacja  certyfikatu klienta bez użycia tej opcji ( gdyż jej nie ma)  nie przebiega pomyślnie. Ale oczywiście mogę się mylić.

8

Odp: Openvpn - dwu stopniowa walidacja

Dzięki wielkie. U mnie też już działa. W sumie robiłem błąd przez swoją nieuwagę. Na razie działa bez hash'a.

Pytanie jak wygenerować hashe do haseł. czy można to zrobić dowolnym programem który robi md5sum ?

9

Odp: Openvpn - dwu stopniowa walidacja

Mozesz online np:
http://www.md5online.pl/

10 (edytowany przez rpc 2013-03-31 21:11:35)

Odp: Openvpn - dwu stopniowa walidacja

@advcron:

Masz nowe wersje plików poprawione pod awk bo rzeczywiście grep nie jest w pełni skompilowany
http://rpc.one.pl/pliki/linux/openvpn/v … CN-cert.sh
http://rpc.one.pl/pliki/linux/openvpn/v … CN-user.sh

teraz powinno działać pod openwrt.
Daj znać czy działa bo pod debianem działa

11 (edytowany przez advcron 2013-04-04 07:46:07)

Odp: Openvpn - dwu stopniowa walidacja

Dziękuję rpc za poprawienie skryptów. Ale dalej mam problem:

Skrypt vpncheckCN-cert.sh jes dobrze poprawiony ( zestawia tunel gdy są dwie kolumny w pliku userlist.txt)

Problem jest z skryptem vpncheckCN-user.
Zrobiłem to tak:

Skrypty sprawdzający haslo - ver-pass-hash.sh

#!/bin/sh
pass=`awk "\\\$1 == \"${username}\" { print substr(\\\$0,length(\\\$1)+2) }" /etc/openvpn/client/openvpn-auth-hash`
## echo $pass >> /etc/openvpn/client/1
echo "grep -q -w "common_name $username" $PWD/userlist.txt && exit 0" >> /etc/openvpn/client/1
test -n "$pass" && test "$pass" == "`printf ${password} | md5sum | awk '{print $1}'`" && grep -q "common_name $username" /etc/openvpn/client/userlist.txt && exit 0
exit 1

Dodałem na końcu twoją regułkę. Usunąłem opcję -w bo dalej tam była. i lipa.
Po komendzie echo w pliku 1 mam:   grep -q -w common_name pk1 /etc/openvpn/client/userlist.txt && exit 0
Podstawiłem więc zamiast wartości common_name nazwę cn z certyfikatu np Jan_Kowalski czyli

#!/bin/sh
pass=`awk "\\\$1 == \"${username}\" { print substr(\\\$0,length(\\\$1)+2) }" /etc/openvpn/client/openvpn-auth-hash`
## echo $pass >> /etc/openvpn/client/1
echo "grep -q -w "common_name $username" $PWD/userlist.txt && exit 0" >> /etc/openvpn/client/1
test -n "$pass" && test "$pass" == "`printf ${password} | md5sum | awk '{print $1}'`" && grep -q "Jan_Kowalski $username" /etc/openvpn/client/userlist.txt && exit 0
exit 1

I Tunel się zestawił.  Wychodzi z tego że nie jest pobierana wartość common_name z certyfikatu.


Żeby nie pisać drugiego postu to poprawiłem ten skrypt oczywiście na podstawie twoich z debiana. Wydaje mi się, że wkradła się literówka. ( ^$common_nam) i chyba teraz działa

#!/bin/sh
pass=`awk "\\\$1 == \"${username}\" { print substr(\\\$0,length(\\\$1)+2) }" /etc/openvpn/client/openvpn-auth-hash`
test -n "$pass" && test "$pass" == "`printf ${password} | md5sum | awk '{print $1}'`" && grep -q "^$common_name $username" /etc/openvpn/client/userlist.txt && exit 0
exit 1

12

Odp: Openvpn - dwu stopniowa walidacja

plik cert porównuje CN z certyfikatu do tego co jest wpisane w pliku userlist.txt. Ergo wystarczy tutaj tylko jedna kolumna z nazwą usera CN
plik user ma inne zadanie(muszą być dwie kolumny). On wspomaga autoryzację pam czy podobną. Znaczy się przypisuje użytkownika który istnieje w systemie (unix - username) do tego który jest w polu CN(common_name). Ale to nie wszystko. User z CN musi być w katalogu ccd. Plik user nie bierze tak naprawdę w validacji certyfikatu udziału.
pliku user nie sprawdzałem ale zerknę do niego jeszcze raz w wolnej chwili.

13 (edytowany przez rpc 2013-04-04 21:56:53)

Odp: Openvpn - dwu stopniowa walidacja

tak to literówka. Trzeba wykasować opcję -w z grep.
Plik user poprawiony

korzystam z pam więc nie analizowałem zbytnio innych przykładów z netu

14

Odp: Openvpn - dwu stopniowa walidacja

Wydaje mi się, że jeszcze tu jest błąd w Twoim skrypcie:
U mnie tylko w takiej postaci działa na poenwrt:

grep -q "^$common_name $username" /etc/openvpn/client/userlist.txt

15

Odp: Openvpn - dwu stopniowa walidacja

tak powinno być bez ^ to regex którego w grep pod openwrt nie obsługuje

16

Odp: Openvpn - dwu stopniowa walidacja

Masz rację tak też działa:

grep -q "$common_name $username" /etc/openvpn/client/userlist.txt

Ogólnie to bardzo dziękuję za pomoc

17

Odp: Openvpn - dwu stopniowa walidacja

Przeczytałem już z 10 raz powyższy poradnik ale dalej mi nie wychodzi konfiguracja. Umiem zrobić już walidację po certyfikacie  oraz haśle i loginie jednocześnie. Jednakże zależy mi, aby było sprawdzane to co zostało opisane wyżej czyli zgodność Cn z certyfikatu klienta z hasłem i loginem danego klienta. W tej chwili mam tak, że klient z danym certyfikatem może posłużyć się hasłem i loginem innego klienta i niestety openwrt dopuszcza do połączenia.

Advacor lub RPC mógłbym Was prosić o podanie pełnej konfiguracji i zawartości wszystkich plików konfiguracyjnych związanych z openvpn ( z pominięciem oczywiście loginów i haseł oraz Ip i mac) Sam już nie wiem gdzie robię błąd lub co pomijam. Dziękuję

18

Odp: Openvpn - dwu stopniowa walidacja

Lepiej użyć uwierzytelniania klientów za pomocą klucza współdzielonego i opcji tls-auth

TP-Link TL-WDR3600 v1.5 -  OpenWrt Chaos Calmer 15.05.1 with Luci +Microsoft LifeCam VX-3000
RaspberryPi 2 - OMV Stone Burner 2.0.15 +Creative SB Play +Medion OR24V +DVB-T Media-Tech MT4163  +MP00202AC +3xDS18B20 +HIH-4000-002 +MPXHZ6115A +Samsung SPF-85H +D-Link DUB-H7

19

Odp: Openvpn - dwu stopniowa walidacja

Khain a jeśli kogoś będę chciał odłączyć to jak to wtedy rozwiązać?

20 (edytowany przez g0f3r 2016-06-27 15:37:15)

Odp: Openvpn - dwu stopniowa walidacja

smereka napisał/a:

Khain a jeśli kogoś będę chciał odłączyć to jak to wtedy rozwiązać?

A co mówi dokumentacja? Chyba dodajesz określone klucze do indeksów? Jeśli dodajesz to i usuwasz.

link

21 (edytowany przez advcron 2016-06-28 09:13:41)

Odp: Openvpn - dwu stopniowa walidacja

Oj dawno już tam nie zglądałem. Mam nadzieję, że regułki są nadal aktualne.
Tu masz:
vpncheckCN-cert (dodane troszkę moich wypocin możesz odchaszować np tworzenie pliku a w nim  zapis parametramów jakie przekazujemy do skryptu. Tak dla testu).

#!/bin/sh
#    vpncheckCN-cert -- an OpenVPN tls-verify script
#    """""""""""""""""""""""""""""""""""""""""""
#
#    This script checks if the peer is in the allowed
#    user list by checking the CN (common name) of the
#    X509 certificate against a provided text file.
#
#    For example in OpenVPN, you could use the directive
#    (as one line):
#
#    tls-verify "/etc/openvpn/vpncheckCN-cert.sh
#                /etc/openvpn/userlist.txt"
#
#    This would cause the connection to be dropped unless
#    the client common name is within the userlist.txt.
#
#    Special care has been taken to ensure that this script
#    also works on openwrt systems where only busybox is
#    available
#
#    Written by Robert Penz <robert[at]penz.name> under the GPL 2
#    Parts are copied from the verify-cn sample OpenVPN
#    tls-verify script.
#
#    Modifications made by Rafal Cichosz (rpc[at]rpc.one.pl)



[ $# -eq 3 ] || { echo usage: ovpnCNcheck.sh userfile certificate_depth X509_NAME_oneline ; exit 255 ; }

# $2 -> certificate_depth
if [ $2 -eq 0 ] ; then
    # $3 -> X509_NAME_oneline
    # $1 -> cn we are looking for
#       echo "grep -q `echo $3 | awk -F"/" '{for (i=1; i<=NF; i++) if ($i ~ /CN=.*/) tmp=substr($i,4)} END {print tmp}'` $1 && exit 0" >> /etc/openvpn/client/1
#       echo "grep -q "^$common_name $username" $PWD/userlist.txt && exit 0" >> /etc/openvpn/client/1

    #script debian
        # grep -q "`expr match "$3" ".*/CN=\([^/][^/]*\)"`$" "$1" && exit 0
    #or other script by openwrt
#    grep -q `echo $3 | awk -F"/" '{for (i=1; i<=NF; i++) if ($i ~ /CN=.*/) tmp=substr($i,4)} END {print tmp}'` $1 && exit 0 

#    echo "grep -q `echo $3 | awk -F"/" '{for (i=1; i<=NF; i++) if ($i ~ /CN=.*/) tmp=substr($i,4)} END {print tmp}'` $1 && exit 0" >> /etc/openvpn/client/2
#    echo "grep -q `echo $3` && exit 1" >> /etc/openvpn/client/2
#    echo "grep -q "`expr match "$3" ".*/CN=\([^/][^/]*\)"`$" "$1" && exit 2" >> /etc/openvpn/client/2
#    echo "grep -q `echo Jan_Nowak` $1 && exit 3"  >> /etc/openvpn/client/2
#    grep -q `echo $3 | awk -F"/" '{for (i=1; i<=NF; i++) if ($i ~ /CN=.*/) tmp=substr($i,4)} END {print tmp}'` $1 && exit 0
#    grep -q `echo Jan_Nowak` $1 && exit 0
#    grep -q "`expr match "$3" ".*/CN=\([^/][^/]*\)"`$" "$1" && exit 0

# Uniwersalne Debian+Openwrt
#    echo "grep -w "`echo "$3" | sed -r 's/.*CN=([^,]*),.*/\1/'`" $1 && exit 0" >> /etc/openvpn/client/2 
    grep -w "`echo "$3" | sed -r 's/.*CN=([^,]*),.*/\1/'`" $1 && exit 0
    exit 1
fi

exit 0

vpncheckCN-user.sh

#!/bin/sh

# auth-user-pass-verify /etc/openvpn/vpncheckCN-user.sh via-env
# 
#Writen by Rafal Cichosz (rpc[at]rpc.one.pl)

###UWAGA !!! Wybierz tylko jeden z poniższych warunków

##############################################################################

###te wiersze stosujemy w momencie kiedy w certyfikacie w polu Common Name mamy
###wpisaną nazwę użytkownika który autoryzuje się poprzez PAM czyli /etc/password
###W pliku userlist.txt mamy tylko jedną kolumnę z nawą usera zdefioniowanego w
### w systemie /etc/passwd i w certyfikacie w polu Common Name np.
###jkowalski

#test "$common_name" == "$username" && exit 0

###############################################################################

###te wiersze stosujemy jeśli przypisanie zdefiniowaliśmy sobie w pliku userlist.txt
###nazwę z certyfikatu - pole Common Name oraz nazwę usera w systemie np. /etc/password
###wedle wzoru
###Common_Name username
###np.
###Jan_Kowalski jkowalski
grep -q -w "^$common_name[[:blank:]]*$username$" /etc/openvpn/client/userlist.txt && exit 0

###############################################################################

###jeżeli powyższy warunek się nie zgadza to odrzuć połączenie


###
#Wersja ponizej jest wtedy jak grep nie skompilowany z opcja -w
#np. w openwrt
#trzeba zwrocic uwage aby byla tylko jedna spacja pomiedzy slowami inaczej nie wykryje
#grep -q -w "common_name $username" /etc/openvpn/client/userlist.txt && exit 0

# grep -q -w "^$common_name[[:blank:]]*$username$" $PWD/userlist.txt && exit 0


###############################################################################

###jeżeli powyższy warunek się nie zgadza to odrzuć połączenie
exit 1

userlist.txt

Jan Nowak user_nowak
adam user_adam

Dodaj sobie też klucz hmac, zawsze to dodatkowe zabezpieczenie. Czyli  login_hasło+cert+hmac_key.

22 (edytowany przez smereka 2016-06-28 11:01:42)

Odp: Openvpn - dwu stopniowa walidacja

Troszkę za szybko jak dla mnie. Napiszę jak ja to rozumiem i potem proszę zweryfikuj to advcron. Identyfikacja po haśle zwykłym to dodanie regułki w pliku /etc/config/openvpn o treści

script-security 3
username-as-common-name
auth-user-pass-verify /etc/openvpn/ver-pass.sh via-env

Gdzie plik ver-pass.sh o zawartości:

#!/bin/sh
pass=`awk "\\\$1 == \"${username}\" { print substr(\\\$0,length(\\\$1)+2) }" /etc/openvpn/openvpn-auth`
test -n "$pass" && test "$pass" == "${password}" && exit 0
exit 1

oraz plik openvpn-auth o zawartości

user1 pass1
user2 pass2

Dodajemy chmod i działa. Do tej pory rozumiem. Teraz chcemy aby CN z certyfikatu zgadzało się z hasłem i loginem konkretnym dla danego klienta. Czyli w pliku konfiguracyjnym dodajemy wpis:

tls-verify "/etc/openvpn/client/vpncheckCN-cert.sh /etc/openvpn/client/userlist.txt"

No i ta regułka wyżej odwołuje się do vpncheckCN-cert którego treść pokazałeś.

Jego treść też zamieściłeś.

Następnie vpncheckCN-user.sh Czyli w pliku konfiguracyjnym dodajemy:

auth-user-pass-verify /etc/openvpn/vpncheckCN-user.sh via-env

Pytania:
1.    Gdzie będzie następowała autoryzacja po haśle do danego loginu? Rozumiem, że
auth-user-pass-verify /etc/openvpn/vpncheckCN-user.sh via-env

zastępuje działanie:

auth-user-pass-verify /etc/openvpn/ver-pass.sh via-env

w którym to ta identyfikacja została poczyniona. Co będzie teraz weryfikowało hasło, które jest podane w openvpn-auth

2.    O co chodzi z /etc/passwd. Mam tam dodać użytkownika nowego? Jeśli tak to jak mam to zrobić? Użytkownik ma być z hasłem czy bez hasła. Jeśli z hasłem to jak te hasło wygenerować i czy hasło ma być zgodne z tym co u klienta się łączącego? I w ogóle jakie regułki wpisać, żeby ten użytkownik postał.
Z góry przepraszam, pewnie za banalne pytania ale dla mnie nie wszystko jest takie jasne i proste. Jest tu sporo fachowców więc proszę o wyrozumiałość. Na pewno wiedza przyda się innym. Dziękuję

23 (edytowany przez advcron 2016-06-28 19:14:49)

Odp: Openvpn - dwu stopniowa walidacja

Zacznijmy od początku:
Polecenie username-as-common-name ->  odchaszowane nazwy plików w ccd takie jak login , zachaszowane takie jak cn w certyfikacie.
Ja mam je zachaszowane, a nazwy plików w ccd takie jak CN certyfikatu.

Następnie:
Pierwszą cześć dobrze rozumujesz.
Mylące dla ciebie jest użycie pliku vpncheckCN-user.sh. Odpowiedź jest prosta. Nie używasz go. Plik ten daje dodatkową walidację loginu i hasła, pod warunkiem, że w systemie masz moduł pam, który to przeprowadza autoryzację. W openwrt tego nie ma, dlatego wykorzystujesz ver-pass.sh, która to najogólniej mówiąc symuluje. Pliki jak i artykuł były napisane w oparciu chyba o Debiana. Dlatego one są.
W openwrt wykorzystujesz jedynie:
auth-user-pass-verify /etc/openvpn/client/ver-pass.sh via-env
tls-verify "/etc/openvpn/client/vpncheckCN-cert.sh /etc/openvpn/client/userlist.txt"

Co do /etc/passwd - tu nic nic nie dodajesz. Jak wspomniałem nie masz pam.

24 (edytowany przez smereka 2016-06-29 09:20:30)

Odp: Openvpn - dwu stopniowa walidacja

Dziękuję advcron za cierpliwość i pomoc. Niestety nie działa to u mnie. Podam jak u mnie to wszystko wygląda. Bo zapewne gdzieś coś nieświadomie psuję. Plik /etc/config/openvpn wygląda następująco:

config openvpn 'sample_server'
    option enabled '1'
    option port '1195'
    option proto 'tcp'
    option dev 'tun'
    option ca '/etc/openvpn/ca.crt'
    option cert '/etc/openvpn/server.crt'
    option key '/etc/openvpn/server.key'
    option dh '/etc/openvpn/dh1024.pem'
    option server '10.8.2.0 255.255.255.0'
    option ifconfig_pool_persist '/tmp/ipp.txt'
    option keepalive '10 120'
    option comp_lzo 'yes'
    option persist_key '1'
    option persist_tun '1'
    option user 'nobody'
    option status '/tmp/openvpn-status.log'
    option verb '3'
    #option username_as_common_name
    option client_config_dir '/etc/openvpn/ccd'


    option client_to_client '1'
    option script_security 3
    option auth_user_pass_verify '/etc/openvpn/ver_pass.sh via-env'
    option tls-verify '/etc/openvpn/vpncheckCN_cert.sh /etc/openvpn/userlist.txt'


/etc/openvpn/ver_pass.sh wygląda następująco:

#!/bin/sh
pass=`awk "\\\$1 == \"${username}\" { print substr(\\\$0,length(\\\$1)+2) }" /etc/openvpn/openvpn_auth`
test -n "$pass" && test "$pass" == "${password}" && exit 0
exit 1


/etc/openvpn/vpncheckCN_cert.sh wygląda następująco:

#!/bin/sh
#    vpncheckCN-cert -- an OpenVPN tls-verify script
#    """""""""""""""""""""""""""""""""""""""""""
#
#    This script checks if the peer is in the allowed
#    user list by checking the CN (common name) of the
#    X509 certificate against a provided text file.
#
#    For example in OpenVPN, you could use the directive
#    (as one line):
#
#    tls-verify "/etc/openvpn/vpncheckCN-cert.sh
#                /etc/openvpn/userlist.txt"
#
#    This would cause the connection to be dropped unless
#    the client common name is within the userlist.txt.
#
#    Special care has been taken to ensure that this script
#    also works on openwrt systems where only busybox is
#    available
#
#    Written by Robert Penz <robert[at]penz.name> under the GPL 2
#    Parts are copied from the verify-cn sample OpenVPN
#    tls-verify script.
#
#    Modifications made by Rafal Cichosz (rpc[at]rpc.one.pl)



[ $# -eq 3 ] || { echo usage: ovpnCNcheck.sh userfile certificate_depth X509_NAME_oneline ; exit 255 ; }

# $2 -> certificate_depth
if [ $2 -eq 0 ] ; then
    # $3 -> X509_NAME_oneline
    # $1 -> cn we are looking for
       echo "grep -q `echo $3 | awk -F"/" '{for (i=1; i<=NF; i++) if ($i ~ /CN=.*/) tmp=substr($i,4)} END {print tmp}'` $1 && exit 0" >> /etc/openvpn/client/1
      echo "grep -q "^$common_name $username" $PWD/userlist.txt && exit 0" >> /etc/openvpn/client/1

    #script debian
        # grep -q "`expr match "$3" ".*/CN=\([^/][^/]*\)"`$" "$1" && exit 0
    #or other script by openwrt
#    grep -q `echo $3 | awk -F"/" '{for (i=1; i<=NF; i++) if ($i ~ /CN=.*/) tmp=substr($i,4)} END {print tmp}'` $1 && exit 0

#    echo "grep -q `echo $3 | awk -F"/" '{for (i=1; i<=NF; i++) if ($i ~ /CN=.*/) tmp=substr($i,4)} END {print tmp}'` $1 && exit 0" >> /etc/openvpn/client/2
#    echo "grep -q `echo $3` && exit 1" >> /etc/openvpn/client/2
#    echo "grep -q "`expr match "$3" ".*/CN=\([^/][^/]*\)"`$" "$1" && exit 2" >> /etc/openvpn/client/2
#    echo "grep -q `echo Jan_Nowak` $1 && exit 3"  >> /etc/openvpn/client/2
#    grep -q `echo $3 | awk -F"/" '{for (i=1; i<=NF; i++) if ($i ~ /CN=.*/) tmp=substr($i,4)} END {print tmp}'` $1 && exit 0
#    grep -q `echo Jan_Nowak` $1 && exit 0
#    grep -q "`expr match "$3" ".*/CN=\([^/][^/]*\)"`$" "$1" && exit 0

# Uniwersalne Debian+Openwrt
    echo "grep -w "`echo "$3" | sed -r 's/.*CN=([^,]*),.*/\1/'`" $1 && exit 0" >> /etc/openvpn/client/2
    grep -w "`echo "$3" | sed -r 's/.*CN=([^,]*),.*/\1/'`" $1 && exit 0
    exit 1
fi

exit 0

Dodane chmod 755 na /etc/openvpn/client/ver-pass.sh i na /etc/openvpn/client/vpncheckCN-cert.sh oraz /etc/openvpn/client/userlist.txt i /etc/openvpn/openvpn_auth

Konfiguracja klienta windows:

# Automatically generated configuration


client
dev tun11
proto udp
remote XXXXXXXXXX 443
resolv-retry 30
nobind
persist-key
persist-tun
comp-lzo adaptive
verb 3
ca ca.crt
cert adam.crt
key adam.key
auth-user-pass password.txt

status-version 2
status status

# Custom Configuration
route 192.168.1.0 255.255.255.0
route 192.168.2.0 255.255.255.0
route 192.168.3.0 255.255.255.0
route 192.168.4.0 255.255.255.0
route 192.168.5.0 255.255.255.0
route 192.168.10.0 255.255.255.0
route 10.8.1.0 255.255.255.0

Gdzie password.txt ma zawartość

adam    <--- login
adam12345 <--- hasło

Działą to tak, że jeśli np klient "adam" ma certyfikat swój ale hasło i login od klienta "krzysiek" to i tak połączenie się nawiązuje. Rozumiem, że to co mi podałeś ma działac tak, że jeli klient "adam" posłuży się się loginem i hasłem od klienta "krzysiek" to połączenie ma nie zostać zestawione? O co tu chodzi, że to nie działa jak powinno?

25 (edytowany przez advcron 2016-06-29 13:43:23)

Odp: Openvpn - dwu stopniowa walidacja

Faktycznie  widzę u siebie, że nie weryfikuje username=CN, a kiedyś działało. Nie potrzebuję tak dokładniej weryfikacji dlatego myślałem że dalej działa.  Kurcze dosyć dawno to konfigurowałem.  Jak dojdę z tym do ładu to dam Ci nać.

Dodane:
Spróbuj tak zmienić plik ver-pass.sh

#!/bin/sh
pass=`awk "\\\$1 == \"${username}\" { print substr(\\\$0,length(\\\$1)+2) }" /etc/openvpn/client/openvpn-auth`
test -n "$pass" && test "$pass" == "${password}" && grep -w "$common_name $username" /etc/openvpn/client/userlist.txt && exit 0
exit 1